创建数据集和我想要使用的功能
library(data.table)
DT <- data.table(V1=c(rep("A",5),rep("B",5)),
V2=rep(1:5,2),
V3=c(10,10,0,0,0,5,10,0,0,0),
V4=c(0,0,0,2,2,0,0,0,4,4))
testFunction<-function(x,transformation){
l<-length(x)
out <- rep(0, l)
out[1] <- x[1]
for (i in 2:l) {
#out[i] <- x[i] + (1 - transformation) * x[i - 1] #EDIT: Function was wrong
out[i] <- x[i] + (1 - transformation) * out[i - 1]
}
return(out)
}
现在我要做的是使用以下应用程序data.frame
中的信息创建一个新数据集newDTapplication<-data.frame(var=c("V3","V3","V4"),
transform=c(0.5,0.9,0.5))
我想从这个函数得到的代码如下:使用应用程序中的变量名称和转换创建新变量,并通过列V1执行此操作。
newDT<-DT[,':='(V3_0.5=testFunction(V3,0.5),
V3_0.9=testFunction(V3,0.9),
V4_0.5=testFunction(V4,0.5)),
by="V1"]
使用几个粘贴函数将其编码为文本,然后将其传递给eval(parse(text = ....))很简单:
application$code<-paste(application$var,"_",application$transform,"=testFunction(",application$var,",",application$transform,")",sep="")
code<-paste("newDT<-DT[,':='(",paste(application$code,collapse=","),"),by='V1']")
eval(parse(text=code))
然而,当您在字符串中传递超过4076个字符时会遇到问题((a)不知道为什么而且(b)不建议在整个Runiverse中使用。)
问题:我该如何解决这个问题?
如果速度不受影响,很高兴看到替代解决方案,例如dplyr。
编辑:输出表应如下所示
V1 V2 V3 V4 V3_0.5 V3_0.9 V4_0.5
1: A 1 10 0 10.0000 10.0000 0
2: A 2 10 0 15.0000 11.0000 0
3: A 3 0 0 7.5000 1.1000 0
4: A 4 0 2 3.7500 0.1100 2
5: A 5 0 2 1.8750 0.0110 3
6: B 1 5 0 5.0000 5.0000 0
7: B 2 10 0 12.5000 10.5000 0
8: B 3 0 0 6.2500 1.0500 0
9: B 4 0 4 3.1250 0.1050 4
10: B 5 0 4 1.5625 0.0105 6
答案 0 :(得分:1)
在您的问题的核心,您可以将参数向量传递给lapply,然后通过引用创建新列,如下所示:
library(data.table)
DT <- data.table(col = 1:5)
expon <- function(y,x){x ^ y}
params <- c(1,5,3)
DT[, (paste0("col_",params, sep = "")) := lapply(params, expon, col)]
这会给你:
col col_1 col_5 col_3
1: 1 1 1 1
2: 2 2 32 8
3: 3 3 243 27
4: 4 4 1024 64
5: 5 5 3125 125
答案 1 :(得分:0)
感谢Chris为我提供了一个正确方向的步骤,并提供了一个可以使用单个列的解决方案。
要扩展到多个列:
#Turn application into a list
applic_list<-unlist(apply(application, 1, list), recursive = FALSE)
#lapply through this list, using .SD to call the column in question
DT[,(paste(application$var,application$transform,sep="_")) :=
lapply(applic_list,function(y) {
testFunction(as.numeric(y[["transform"]]),.SD[[y[["var"]]]])
}),by="V1"]
返回
V1 V2 V3 V4 V3_0.5 V3_0.9 V4_0.5
1: A 1 10 0 10.0000 10.0000 0
2: A 2 10 0 15.0000 11.0000 0
3: A 3 0 0 7.5000 1.1000 0
4: A 4 0 2 3.7500 0.1100 2
5: A 5 0 2 1.8750 0.0110 3
6: B 1 5 0 5.0000 5.0000 0
7: B 2 10 0 12.5000 10.5000 0
8: B 3 0 0 6.2500 1.0500 0
9: B 4 0 4 3.1250 0.1050 4
10: B 5 0 4 1.5625 0.0105 6