通过在其他列上应用函数来创建新的data.table列

时间:2018-01-20 22:15:59

标签: r data.table

我想根据其他列的值在data.table中创建一个新列。以mtcars为例:

> library(data.table)
> dt <- as.data.table(mtcars)
> head(dt[, newval := cyl + gear])
    mpg cyl disp  hp drat    wt  qsec vs am gear carb newval
1: 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4     10
2: 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4     10
3: 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1      8
4: 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1      9
5: 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2     11
6: 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1      9

工作正常,但即使是稍微复杂的功能,我收到警告信息:

simple_func <- function(a, b){
  if(a %in% c(4,6)  ){
    return(a*b)
  }else{
    return(b/a)
  }
}

head(dt[, newval := simple_func(cyl, disp)])

返回:

> head(dt[, newval := simple_func(cyl, disp)])
    mpg cyl disp  hp drat    wt  qsec vs am gear carb newval
1: 21.0   6  160 110 3.90 2.620 16.46  0  1    4    4    960
2: 21.0   6  160 110 3.90 2.875 17.02  0  1    4    4    960
3: 22.8   4  108  93 3.85 2.320 18.61  1  1    4    1    432
4: 21.4   6  258 110 3.08 3.215 19.44  1  0    3    1   1548
5: 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2   2880
6: 18.1   6  225 105 2.76 3.460 20.22  1  0    3    1   1350
Warning message:
In if (a %in% c(4, 6)) { :
  the condition has length > 1 and only the first element will be used

第5行(cyl == 8)的值明显不正确,newval的预期值为45。

原因是该函数不是一次评估一行而是整个列,因此如果满足第一行(dt$cyl[1], dt$disp[1])的条件,则所有其他行都具有相同的公式appllied给他们。

我如何解决这个问题?我尝试使用.SDcols,但没有做对,而是遇到了其他错误。

1 个答案:

答案 0 :(得分:1)

使用ifelse

simple_func <- function(a, b){
    ifelse(a %in% c(4,6), a*b, b/a)
}
相关问题