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

时间:2019-02-06 13:18:10

标签: r function dataframe tidyverse arithmetic-expressions

鉴于下面的示例数据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

在此先感谢您的帮助。

3 个答案:

答案 0 :(得分: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 :(得分: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

答案 2 :(得分:1)

这是一种UseSqlServer可能性:

tidyverse