[英]R: Create new variables in data.table from a separate list of parameters
創建數據集和我要使用的功能
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)
}
現在我要做的就是使用來自以下應用程序數據的信息創建一個新的數據集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)不知道為什么,並且不建議在整個Runiverse中使用(b))。
問題:我該如何處理?
如果不影響速度,很高興查看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
深入到問題的核心,您可以將參數向量傳遞給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
感謝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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.