如何将函数应用于几列中每列的子集?

时间:2019-09-11 04:01:50

标签: r data.table

假设我有一个data.table,像这样:

> test.dt = data.table(alice = 2:-1, bob = -1:2, claire = 0:-1, x = 2:5)
> test.dt
   alice bob claire x
1:     2  -1      0 2
2:     1   0     -1 3
3:     0   1      0 4
4:    -1   2     -1 5

但是通常,除了“ alice”,“ bob”和“ claire”以外,还有更多名称,它们存储在向量中

names = c("alice", "bob", "claire")

与“ alice”,“ bob”或“ claire”不同,列“ x”是不在names中的特殊列。

假设我有一个函数f(name, x)接受矢量输入。我想执行以下操作:在名称为names的每一列中,将所有正值替换为f(name, x),其他值保持不变。

这似乎很简单,可以在熊猫中完成以下操作(将test.dt重命名为df):

for name in names:
    df.loc[df[name] > 0, name] = f(df.loc[df[name] > 0, name],
                                   df.loc[df[name] > 0, "x"])

但是我不知道如何在R中做到这一点。

2 个答案:

答案 0 :(得分:2)

使用(在这种情况下)可能是一个不错的选择(如下所示)(如下所示)使用for循环(使用与@Ronak相同的功能):

for (n in nms) {
  test.dt[get(n) > 0, (n) := f(get(n), 2L)]
}

给出:

> test.dt
   alice bob claire x
1:     4  -1      0 2
2:     2   0     -1 3
3:     0   2      0 4
4:    -1   4     -1 5

注意:尽量避免给对象起一个与函数相同的名称;因此我将names向量重命名为nms

答案 1 :(得分:0)

考虑一个功能

f <- function(x, n) x * n

我们可以使用.SDcols通过名称指定列

library(data.table)
test.dt[, (names) := lapply(.SD, function(x) ifelse(x > 0, f(x, 2), x)), .SDcols = names]

test.dt
#   alice bob claire x
#1:     4  -1      0 2
#2:     2   0     -1 3
#3:     0   2      0 4
#4:    -1   4     -1 5