【问题标题】:Calling user defined function from data.table object从 data.table 对象调用用户定义的函数
【发布时间】:2020-04-21 13:25:39
【问题描述】:

我正在尝试调用用户定义的函数来创建一个新列,该列取决于我的 data.table 的其他列的值。在简单的情况下,我没有遇到任何错误,但是当我使用条件语句或循环时,看起来好像用户定义的函数接收了整个列作为参数。

从其他有关堆栈溢出的案例中学习(例如:R data.table user defined function),我了解到使用 ifelse 函数的 if 语句可以克服这个问题。但是,我找不到循环语句的解决方案。

请看下面我要运行的代码,它返回以下错误消息:Error in seq.default(1, a, 1) : 'to' must be of length 1

test <-data.table(a=c(1,2))

f <- function(a) {
  out <- 0
  for (i in seq(1,a,1)){
    out <- out +1
  }
  return(out)
}

test[,b:=f(a)]

显然,f(x)=x 但为了简单起见,我选择了这个函数。另请注意,将seq(1,a,1) 替换为1:a 会引发以下警告消息:In 1:a : numerical expression has 2 elements: only the first used


以下是对所需行为的更详细说明。

test <-data.table(a=c(1,2,3),b=c(4,5,6))
f <- function(a,b){
  out <-0
  for (i in seq(1,a,1)){
    out <- out + b^(i) 
  }
  return(out)
}

我想让test[,c=f(a,b)] 给:

test
# a b c
# 1 4 4
# 2 5 30    # 5 + 5^2
# 3 6 258   # 6 + 6^2 + 6^3

有没有办法获得所需的行为?

【问题讨论】:

  • 是的,这就是问题的根源。但是,对于dt&lt;-data.table(a=c(1,2)),以这种方式调用g&lt;-function(a){return(a)}dt[,b:=g(a)] 会导致期望的结果。函数 g 只接受一个参数(行中的那个),而不是整行。
  • 再次感谢您的回答。我要使用的功能比这个更复杂,它需要使用一列的元素作为要完成的循环数。我想不出任何解决方法。例如,输入列1,2,3 我希望输出列1,2+2^2,3+3^2+3^3 调用函数f &lt;- function(a){out&lt;-0/n for (i in 1:a){out&lt;- out + a^a}/n return(a)}
  • 不,因为这样,每一行都会得到相同的结果。我将通过对所需结果的更详细解释来更新问题。谢谢!

标签: r data.table


【解决方案1】:

解决问题的两种解决方案(感谢@chinsoon12):

test[,c:=mapply(f, test[,a],test[,b])]

test[,c:=f(a,b),1L:nrow(test)]

在速度方面,这两种解决方案是等价的:

a<-1:500
b<-500:1

test_1 <- data.table(a,b)
test_2 <- data.table(a,b)

bench <- microbenchmark(v_1 = test_1[,c:=mapply(f,test_1[,a],test_1[,b])],v_2 = test_2[,c:=f(a,b),1L:nrow(test_2)],times=100L)

summary(bench)
#  expr      min       lq     mean   median       uq      max neval cld
#1  v_1 91.83598 95.63639 97.82780 96.94672 98.51073 113.2232   100   a
#2  v_2 91.72392 95.45878 98.92037 96.53573 98.71301 139.9906   100   a

autoplot(bench)

Benchmark plot

【讨论】:

  • 另一个选项是test[, v := f(a, b), 1L:nrow(test)],在这种情况下,test[, v := sum(cumprod(rep(b, a))), 1L:nrow(test)]
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-29
  • 1970-01-01
  • 2020-04-28
  • 2020-03-01
  • 2020-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多