【发布时间】:2016-10-25 15:22:11
【问题描述】:
创建一个数据集和我要使用的函数
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 中的信息创建一个新数据集 newDT
application<-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
【问题讨论】:
-
使用
testFunction<-function(x,transformation){x+(1-transformation)*shift(x, fill=0)} -
抱歉,投反对票,因为这样做是个坏主意(不必要地迭代并在字符串中编写代码进行评估)。
-
@ExperimenteR 我怀疑这会奏效。可能需要在某处有一个累积和或累积乘积来绕过迭代。
-
@Frank,恕我直言,没有理由否决这个 Q,因为它显示了 OP 为解决他的问题而付出的巨大努力。而且,Q 是关于如何做得更好。
-
@UweBlock 我也太宽泛了。如果将其简化为一个问题(
testFunction本身就是一个相当大的问题),那将有所帮助。我用我的 DV 作为路标,告诉那些后来偶然发现它的人“这是个坏主意”。这是一个有效的,尽管是主观的原因。如果您将鼠标悬停在向下投票箭头上,我指的是“没用”。
标签: r data.table