R 使用条件函数在data.table()中分配多列

R 使用条件函数在data.table()中分配多列,r,data.table,R,Data.table,在前面的一个问题中,有人明确指出,尽管dlpyr在0.2版中无法从函数返回的向量创建新变量,但data.table()可以使用以下语法-: it[, c(paste0("V", 4:5)) := myfun(V2, V3)] 如果该问题中的函数myfun更改为-: myfun = function(arg1,arg2) { if (arg1 > arg2) { temp1 = arg1 + arg2 temp2 = arg1 - arg2 } else { temp1 = arg1

在前面的一个问题中,有人明确指出,尽管dlpyr在0.2版中无法从函数返回的向量创建新变量,但data.table()可以使用以下语法-:

it[, c(paste0("V", 4:5)) := myfun(V2, V3)]
如果该问题中的函数
myfun
更改为-:

myfun = function(arg1,arg2) {


if (arg1 > arg2) {
temp1 = arg1 + arg2
temp2 = arg1 - arg2 }
else {
temp1 = arg1 * arg2
temp2 = arg1 / arg2 }
list(temp1,temp2)

}
上面发布的解决方案返回警告-:

it = data.table(c("a","a","b","b","c"),c(1,2,3,4,5), c(2,3,4,2,2))
it[, c(paste0("V", 4:5)) := myfun(V2, V3)]

Warning message:
In if (arg1 > arg2) { :
  the condition has length > 1 and only the first element will be used

这意味着data.table()以某种方式向函数传递了不止一行。为什么会发生这种情况?

罗恩,这是预期的行为<代码>数据。表始终传递完整的列(除非您使用
by
,在这种情况下,您将获得与每个子组对应的列部分)。为了解决这个问题,您需要对函数进行矢量化:

myfun2 = function(arg1,arg2) {
  temp1 <- ifelse(arg1 > arg2, arg1 + arg2, arg1 * arg2)
  temp2 <- ifelse(arg1 > arg2, arg1 - arg2, arg1 / arg2)
  list(temp1,temp2)
}
如果不想修改函数,另一种选择是将
data.table
拆分为一行组。为此,我们将一个向量传递给
by
,该向量在
data.table
中的每一行都有一个不同的值(因此每一行都是一个组):


请注意
by
参数。这同样有效,但速度较慢。一般来说,如果你能矢量化,你应该这样做。

Ron,这是预期的行为<代码>数据。表始终传递完整的列(除非您使用
by
,在这种情况下,您将获得与每个子组对应的列部分)。为了解决这个问题,您需要对函数进行矢量化:

myfun2 = function(arg1,arg2) {
  temp1 <- ifelse(arg1 > arg2, arg1 + arg2, arg1 * arg2)
  temp2 <- ifelse(arg1 > arg2, arg1 - arg2, arg1 / arg2)
  list(temp1,temp2)
}
如果不想修改函数,另一种选择是将
data.table
拆分为一行组。为此,我们将一个向量传递给
by
,该向量在
data.table
中的每一行都有一个不同的值(因此每一行都是一个组):


请注意
by
参数。这同样有效,但速度较慢。通常,如果您可以矢量化,您应该。

该警告来自您的函数。仅仅做
myfun(it$V2,it$V3)
就会给出同样的警告。这是因为在执行
arg1>arg2
时,您正在比较两个向量(长度>1)。因此,它只接受第一个值(并提供警告)。该警告来自您的函数。仅仅做
myfun(it$V2,it$V3)
就会给出同样的警告。这是因为在执行
arg1>arg2
时,您正在比较两个向量(长度>1)。因此,它只接受第一个值(并提供警告)。
it[, c(paste0("V", 4:5)) := myfun(V2, V3), by=1:nrow(it)]