R 将函数输出作为新列添加到data.table,而不命名它们

R 将函数输出作为新列添加到data.table,而不命名它们,r,function,data.table,append,multiple-columns,R,Function,Data.table,Append,Multiple Columns,我有一个函数,它从现有data.table中获取某些列作为输入,对它们执行计算,然后将结果作为五个新列输出 我想将这五个新列附加到现有的data.table中,但在不命名列的情况下找不到合适的方法(这似乎是多余的,因为这些列已经在函数的输出中命名,并且它已经输出了data.table) 注意:我的实函数不是矢量化的,所以我必须使用'by'参数 此外,我的实函数是另一个生成模型输出的函数的包装器,因此我将该输出转换为带有as.data.table(pixiedust::dust(…)的表,这样我就

我有一个函数,它从现有data.table中获取某些列作为输入,对它们执行计算,然后将结果作为五个新列输出

我想将这五个新列附加到现有的data.table中,但在不命名列的情况下找不到合适的方法(这似乎是多余的,因为这些列已经在函数的输出中命名,并且它已经输出了data.table)

注意:我的实函数不是矢量化的,所以我必须使用'by'参数

此外,我的实函数是另一个生成模型输出的函数的包装器,因此我将该输出转换为带有
as.data.table(pixiedust::dust(…)
的表,这样我就不必多次运行它来获得输出的每个元素

以下是一个玩具示例:

# Load data.table:
library(data.table)

# Create data.table with example data:
mydt <- data.table(region = c("a", "b", "c"), 
                   count = c(0,50,200), 
                   pop = c(1000, 10000, 20000))

# Toy function:
rate <- function(count, pop, denom){

  dt = data.table(rawrate = count/pop, 
                  rateperpop = (count/pop)*denom)
  return(dt)

}

# Apply the function to mydt:
mydt[, rate(count = count, pop = pop, denom = 100000), by = 1:nrow(mydt)]

# which gives:
   nrow rawrate rateperpop
1:    1   0.000          0
2:    2   0.005        500
3:    3   0.010       1000

。。。但这也不会添加列

如果我尝试:

mydt[, .(rate(count = count, pop = pop, denom = 100000)), by = 1:nrow(mydt)]
由于
by
子句,我得到了一个错误,甚至删除它(我不能用我的实函数)只输出新变量,它不会将它们添加到现有的data.table中


我确信必须有一种语法简洁的方法来做到这一点,但我无法找到它-任何解决方案都将不胜感激

一个选项是创建一个临时对象,然后在LHS上使用
:=
名称的输出

new <- mydt[, rate(count = count, pop = pop, denom = 100000)]
mydt[, names(new) := new]

new一个选项是创建一个临时对象,然后在LHS上使用
:=
名称的输出

new <- mydt[, rate(count = count, pop = pop, denom = 100000)]
mydt[, names(new) := new]

new如果需要添加新列,请执行
:=
。此外,还不清楚为什么会出现
by
needed@Akrun如果我使用
:=
我不需要在左侧添加列名吗?这就是我试图避免的…在这个玩具示例中不需要
by
,但它是我真正的函数,因为它不是vectorised@IceCreamToucan您的意思是将mydt作为输入参数添加到函数中吗?如果需要添加新列,请执行
:=
。此外,还不清楚为什么会出现
by
needed@Akrun如果我使用
:=
我不需要在左侧添加列名吗?这就是我试图避免的…在这个玩具示例中不需要
by
,但它是我真正的函数,因为它不是vectorised@IceCreamToucan您的意思是将mydt作为输入参数添加到函数中吗?这是我通常会做的,但在本例中,我使用的是
exactci::poisson.exact()
获取我的费率的上下置信区间。该函数为每个参数取一个或两个值,如果改为给定向量,则返回一个错误。我可以分别从函数中提取每个元素,并将其添加到data.table,正如您在上面所做的那样,但这会增加不必要的计算时间,因为我将重复函数以获取包装函数中的每个元素。另一方面,刚刚检查了单独调用元素的开销,也许这就是解决方法,因为使用
pixiedust::dust()
也会增加一些计算开销,最好避免额外的包依赖性。您在评论中提出的建议也适用于我,因此我会接受这个答案。这是我通常会做的,但在这种情况下,我使用
exactci::poisson.exact()
来获得我的费率的上下置信区间。该函数为每个参数取一个或两个值,如果改为给定向量,则返回一个错误。我可以分别从函数中提取每个元素,并将其添加到data.table,正如您在上面所做的那样,但这会增加不必要的计算时间,因为我将重复函数以获取包装函数中的每个元素。另一方面,刚刚检查了单独调用元素的开销,也许这就是解决方法,因为使用
pixiedust::dust()
也会增加一些计算开销,最好避免额外的包依赖性。你在评论中的建议对我也很有效,所以我会接受这个答案。
rate <- function(dt, count, pop, denom){
  dt[, `:=`(rawrate = count/pop, 
            rateperpop = (count/pop)*denom)]
}

mydt
#    region count   pop
# 1:      a     0  1000
# 2:      b    50 10000
# 3:      c   200 20000

rate(mydt, count = count, pop = pop, denom = 100000)

mydt
#    region count   pop rawrate rateperpop
# 1:      a     0  1000   0.000          0
# 2:      b    50 10000   0.005        500
# 3:      c   200 20000   0.010       1000