我想根据其他列的值在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
,但没有做对,而是遇到了其他错误。
答案 0 :(得分:1)
使用ifelse
simple_func <- function(a, b){
ifelse(a %in% c(4,6), a*b, b/a)
}