Home > front end >  How do I ask R to subtract adjacent columns in a dataframe?
How do I ask R to subtract adjacent columns in a dataframe?

Time:02-27

Basically, I have 14 columns of numerical variables (say v1 to v14), and I want R to do the following mutation:

v1=v1-v2
v3=v3-v4
v5=v5-v6
...

Here is what I tried. I called all the odd-column variables 'source_vars' and the even-column variables 'use_vars', and tried the following

# Defining source and use vars
source_vars<-c("ofc_s","privnonfin_s","hh_s",
             "ROW_s", "total_s", "banking_s", "totgov_s")
use_vars<-c("ofc_u","privnonfin_u","hh_u",
               "ROW_u", "total_u", "banking_u", "totgov_u")

new<-sw_flows%>%filter(sector=="Total")%>%
  mutate(sector="Source-Use", source_vars=source_vars-use_vars)

This didnt work.

Is there an efficient way to do this without having to name the variables?

CodePudding user response:

Here is a purrr one-liner.
I first create a test data set, then get the odd and even column numbers with the modulus operator and finally use map2 to apply function - to the columns.

set.seed(2022)
df1 <- matrix(rnorm(10*14), ncol = 14)
df1 <- as.data.frame(df1)

source_vars <- which(seq.int(ncol(df1)) %% 2 == 1)
use_vars <- seq.int(ncol(df1))[-source_vars]

purrr::map2_dfc(df1[source_vars], df1[use_vars], `-`)
#> # A tibble: 10 x 7
#>         V1      V3      V5      V7     V9    V11     V13
#>      <dbl>   <dbl>   <dbl>   <dbl>  <dbl>  <dbl>   <dbl>
#>  1 -0.106   0.247  -1.96   -1.20   -1.76  -0.861 -1.38  
#>  2 -0.988  -0.448  -0.188  -2.62    1.61  -0.221  0.636 
#>  3  0.0843  2.67   -1.31   -0.746   0.648  1.25  -1.27  
#>  4 -1.54    1.43   -2.67    0.0901 -0.706  0.667  1.43  
#>  5 -0.278   0.469  -0.249  -2.14   -5.08   1.00   2.69  
#>  6 -2.82   -1.94   -1.43    0.185   1.14   2.47  -0.0427
#>  7 -0.405  -0.430   0.317  -2.16    3.22   0.448 -2.23  
#>  8  1.23    0.186  -1.44   -0.294   0.667 -0.749  0.205 
#>  9 -0.270  -0.675  -0.851   0.838   2.50  -0.597 -0.246 
#> 10 -0.617  -0.0703 -0.0478 -0.464  -0.513  2.17   1.94

Created on 2022-02-26 by the reprex package (v2.0.1)


And a base R way.

res <- Map(\(x, y) x - y, df1[source_vars], df1[use_vars])
do.call(cbind.data.frame, res)

Created on 2022-02-26 by the reprex package (v2.0.1)

CodePudding user response:

If we want to subtract odd from even column sequence columns (assuming there are equal number of even/odd columns

sw_flows[c(TRUE, FALSE)] - sw_flows[c(FALSE, TRUE)]
  • Related