如何创建一个函数来有条件地执行多列算术运算

问题描述 投票:0回答:3

下面给出样本数据sampleDT,我希望得到任何帮助创建一个功能能够有效地执行以下操作:

对于每一个变量,其名称以dollar

  • 在做这些行3-(5/j)其中sampleDT$employer==1;
  • 在做这些行2*j其中sampleDT$employer==0;
  • 放操作的结果在位于紧挨着一个其中它是基于该列的新变量;
  • 保持dollar.wage_1不变的值;
  • 投入运行的产量在新的变量euro.wage_x他的名字只替换dollar通过euro源变量dollar.wage_xxdollar.wage变量的数目。
  • 创建一个名为division.wage_x新的变量包含每对dollar.wage_xeuro.wage_x通过dollar.wage_x euro.wage_x分工的结果。

j代表这两个变量dollar.wage_1:dollar.wage_10取值。


样本数据

sampleDT<-structure(list(id = 1:10, N = c(10L, 10L, 10L, 10L, 10L, 10L, 
    10L, 10L, 10L, 10L), A = c(62L, 96L, 17L, 41L, 212L, 143L, 143L, 
    143L, 73L, 73L), B = c(3L, 1L, 0L, 2L, 170L, 21L, 0L, 33L, 62L, 
    17L), C = c(0.05, 0.01, 0, 0.05, 0.8, 0.15, 0, 0.23, 0.85, 0.23
    ), employer = c(1L, 1L, 0L, 1L, 0L, 1L, 1L, 0L, 0L, 0L), F = c(0L, 
    0L, 0L, 0L, 0L, 1L, 1L, 1L, 1L, 1L), G = c(1.94, 1.19, 1.16, 
    1.16, 1.13, 1.13, 1.13, 1.13, 1.12, 1.12), H = c(0.14, 0.24, 
    0.28, 0.28, 0.21, 0.12, 0.17, 0.07, 0.14, 0.12), dollar.wage_1 = c(1.94, 
    1.19, 3.16, 3.16, 1.13, 1.13, 2.13, 1.13, 1.12, 1.12), dollar.wage_2 = c(1.93, 
    1.18, 3.15, 3.15, 1.12, 1.12, 2.12, 1.12, 1.11, 1.11), dollar.wage_3 = c(1.95, 
    1.19, 3.16, 3.16, 1.14, 1.13, 2.13, 1.13, 1.13, 1.13), dollar.wage_4 = c(1.94, 
    1.18, 3.16, 3.16, 1.13, 1.13, 2.13, 1.13, 1.12, 1.12), dollar.wage_5 = c(1.94, 
    1.19, 3.16, 3.16, 1.14, 1.13, 2.13, 1.13, 1.12, 1.12), dollar.wage_6 = c(1.94, 
    1.18, 3.16, 3.16, 1.13, 1.13, 2.13, 1.13, 1.12, 1.12), dollar.wage_7 = c(1.94, 
    1.19, 3.16, 3.16, 1.14, 1.13, 2.13, 1.13, 1.12, 1.12), dollar.wage_8 = c(1.94, 
    1.19, 3.16, 3.16, 1.13, 1.13, 2.13, 1.13, 1.12, 1.12), dollar.wage_9 = c(1.94, 
    1.19, 3.16, 3.16, 1.13, 1.13, 2.13, 1.13, 1.12, 1.12), dollar.wage_10 = c(1.94, 
    1.19, 3.16, 3.16, 1.13, 1.13, 2.13, 1.13, 1.12, 1.12)), row.names = c(NA, 
    -10L), class = "data.frame")

头输出

id N A  B  C   employer F G    H      dollar.wage_1 dollar.wage_2 dollar.wage_3 dollar.wage_4 dollar.wage_5 dollar.wage_6 dollar.wage_7 dollar.wage_8 dollar.wage_9 dollar.wage_10
1 10 62 3 0.05        1 0 1.94 0.14          1.94          1.93          1.95          1.94          1.94          1.94          1.94          1.94          1.94           1.94
2 10 96 1 0.01        1 0 1.19 0.24          1.19          1.18          1.19          1.18          1.19          1.18          1.19          1.19          1.19           1.19
3 10 17 0 0.00        0 0 1.16 0.28          3.16          3.15          3.16          3.16          3.16          3.16          3.16          3.16          3.16           3.16

我在寻找一个有效的方式做到这一点,因为我的实际数据集有1000多变量dollar.wage_x,其中x > 1000

在此先感谢您的帮助。

r function dataframe tidyverse arithmetic-expressions
3个回答
1
投票

使用data.table

library(data.table)
setDT(sampleDT)
o_cols <- grep("^dollar", names(sampleDT), value = TRUE)
n_cols <- sub("^dollar", "euro", o_cols)
sampleDT[, (n_cols) := lapply(.SD, function(j) ifelse(employer == 1, 3 - 5 / j, 2 * j)), .SDcols = o_cols]



> sampleDT
    id  N   A   B    C employer F    G    H dollar.wage_1 dollar.wage_2 dollar.wage_3 dollar.wage_4 dollar.wage_5 dollar.wage_6 dollar.wage_7
 1:  1 10  62   3 0.05        1 0 1.94 0.14          1.94          1.93          1.95          1.94          1.94          1.94          1.94
 2:  2 10  96   1 0.01        1 0 1.19 0.24          1.19          1.18          1.19          1.18          1.19          1.18          1.19
 3:  3 10  17   0 0.00        0 0 1.16 0.28          3.16          3.15          3.16          3.16          3.16          3.16          3.16
 4:  4 10  41   2 0.05        1 0 1.16 0.28          3.16          3.15          3.16          3.16          3.16          3.16          3.16
 5:  5 10 212 170 0.80        0 0 1.13 0.21          1.13          1.12          1.14          1.13          1.14          1.13          1.14
 6:  6 10 143  21 0.15        1 1 1.13 0.12          1.13          1.12          1.13          1.13          1.13          1.13          1.13
 7:  7 10 143   0 0.00        1 1 1.13 0.17          2.13          2.12          2.13          2.13          2.13          2.13          2.13
 8:  8 10 143  33 0.23        0 1 1.13 0.07          1.13          1.12          1.13          1.13          1.13          1.13          1.13
 9:  9 10  73  62 0.85        0 1 1.12 0.14          1.12          1.11          1.13          1.12          1.12          1.12          1.12
10: 10 10  73  17 0.23        0 1 1.12 0.12          1.12          1.11          1.13          1.12          1.12          1.12          1.12
    dollar.wage_8 dollar.wage_9 dollar.wage_10 euro.wage_1 euro.wage_2 euro.wage_3 euro.wage_4 euro.wage_5 euro.wage_6 euro.wage_7 euro.wage_8 euro.wage_9
 1:          1.94          1.94           1.94   0.4226804   0.4093264   0.4358974   0.4226804   0.4226804   0.4226804   0.4226804   0.4226804   0.4226804
 2:          1.19          1.19           1.19  -1.2016807  -1.2372881  -1.2016807  -1.2372881  -1.2016807  -1.2372881  -1.2016807  -1.2016807  -1.2016807
 3:          3.16          3.16           3.16   6.3200000   6.3000000   6.3200000   6.3200000   6.3200000   6.3200000   6.3200000   6.3200000   6.3200000
 4:          3.16          3.16           3.16   1.4177215   1.4126984   1.4177215   1.4177215   1.4177215   1.4177215   1.4177215   1.4177215   1.4177215
 5:          1.13          1.13           1.13   2.2600000   2.2400000   2.2800000   2.2600000   2.2800000   2.2600000   2.2800000   2.2600000   2.2600000
 6:          1.13          1.13           1.13  -1.4247788  -1.4642857  -1.4247788  -1.4247788  -1.4247788  -1.4247788  -1.4247788  -1.4247788  -1.4247788
 7:          2.13          2.13           2.13   0.6525822   0.6415094   0.6525822   0.6525822   0.6525822   0.6525822   0.6525822   0.6525822   0.6525822
 8:          1.13          1.13           1.13   2.2600000   2.2400000   2.2600000   2.2600000   2.2600000   2.2600000   2.2600000   2.2600000   2.2600000
 9:          1.12          1.12           1.12   2.2400000   2.2200000   2.2600000   2.2400000   2.2400000   2.2400000   2.2400000   2.2400000   2.2400000
10:          1.12          1.12           1.12   2.2400000   2.2200000   2.2600000   2.2400000   2.2400000   2.2400000   2.2400000   2.2400000   2.2400000
    euro.wage_10
 1:    0.4226804
 2:   -1.2016807
 3:    6.3200000
 4:    1.4177215
 5:    2.2600000
 6:   -1.4247788
 7:    0.6525822
 8:    2.2600000
 9:    2.2400000
10:    2.2400000

1
投票

或基础R:

sampleDT[, grepl("dollar", colnames(sampleDT))] <- 
  lapply(sampleDT[ , grepl("dollar", colnames(sampleDT))],
        function(x) {
          res <- 3 - 5 * x
          res[sampleDT$employer==0] <- 2 * x[sampleDT$employer==0]
          res
        } )

1
投票

这里是一个tidyverse可能性:

sampleDT %>% 
 mutate_at(vars(contains("dollar")), funs(euro.wage = ifelse(employer == 1, 3-(5/.), 2*.))) %>%
 rename_at(vars(contains("euro.wage")), 
           funs(paste(sub(".*\\_", "", .), gsub("[^0-9]", "\\1", .), sep = "_"))) 


   id  N   A   B    C employer F    G    H dollar.wage_1 dollar.wage_2
1   1 10  62   3 0.05        1 0 1.94 0.14          1.94          1.93
2   2 10  96   1 0.01        1 0 1.19 0.24          1.19          1.18
3   3 10  17   0 0.00        0 0 1.16 0.28          3.16          3.15
4   4 10  41   2 0.05        1 0 1.16 0.28          3.16          3.15
5   5 10 212 170 0.80        0 0 1.13 0.21          1.13          1.12
6   6 10 143  21 0.15        1 1 1.13 0.12          1.13          1.12
7   7 10 143   0 0.00        1 1 1.13 0.17          2.13          2.12
8   8 10 143  33 0.23        0 1 1.13 0.07          1.13          1.12
9   9 10  73  62 0.85        0 1 1.12 0.14          1.12          1.11
10 10 10  73  17 0.23        0 1 1.12 0.12          1.12          1.11
   dollar.wage_3 dollar.wage_4 dollar.wage_5 dollar.wage_6 dollar.wage_7
1           1.95          1.94          1.94          1.94          1.94
2           1.19          1.18          1.19          1.18          1.19
3           3.16          3.16          3.16          3.16          3.16
4           3.16          3.16          3.16          3.16          3.16
5           1.14          1.13          1.14          1.13          1.14
6           1.13          1.13          1.13          1.13          1.13
7           2.13          2.13          2.13          2.13          2.13
8           1.13          1.13          1.13          1.13          1.13
9           1.13          1.12          1.12          1.12          1.12
10          1.13          1.12          1.12          1.12          1.12
   dollar.wage_8 dollar.wage_9 dollar.wage_10 euro.wage_1 euro.wage_2 euro.wage_3
1           1.94          1.94           1.94   0.4226804   0.4093264   0.4358974
2           1.19          1.19           1.19  -1.2016807  -1.2372881  -1.2016807
3           3.16          3.16           3.16   6.3200000   6.3000000   6.3200000
4           3.16          3.16           3.16   1.4177215   1.4126984   1.4177215
5           1.13          1.13           1.13   2.2600000   2.2400000   2.2800000
6           1.13          1.13           1.13  -1.4247788  -1.4642857  -1.4247788
7           2.13          2.13           2.13   0.6525822   0.6415094   0.6525822
8           1.13          1.13           1.13   2.2600000   2.2400000   2.2600000
9           1.12          1.12           1.12   2.2400000   2.2200000   2.2600000
10          1.12          1.12           1.12   2.2400000   2.2200000   2.2600000
© www.soinside.com 2019 - 2024. All rights reserved.