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)]