2014-02-06 47 views
1

我有兩個data.table(s)DT1和RF,其中DT1是主表,RF是變量值的crosswalk。如何傳遞列名作爲來自其他列表的輸入並引用其他data.table來總計分數?

DT1 <- data.table(id = c(1:10),Var1=c(1,0,0,0,1,0,1,1,0,0) ,Var2=c(0,0,0,0,1,0,1,0,0,1), 
       Var3=c(1,1,1,0,0,0,1,1,0,0),Var4=c(1,1,0,0,1,0,0,0,0,0), 
       Var5=c(0,0,0,0,1,0,1,1,0,0)) 
RF <- data.table (Variable = c("Var1","Var2","Var3","Var4","Var5","Var6","Var7","Var8", 
       "Var9","Var10"), 
       CO = c(1.1,2.3,1.4,1.5,1.0,3.8,2.5,3.7,2.1,2.0), 
       IN = c(2.1,1.3,1.9,2.5,1.7,2.8,2.9,1.7,1.1,2.0)) 

欲計算在DT1模型CO和其中添加劑,並會採取不同的變量作爲兩者的模型輸入一個得分列。對於我創建的變量列出了兩種型號:

List1 <- c("Var1","Var3","Var5") 
List2 <- c("Var1","Var2","Var6","Var7","Var8") 

所以,如果我計算Score_CO那麼我的工作,應在列表1檢查變量。像在DT1每一行應該檢查是否

1) Var1 == 1, If yes, 
2) then check for that in RF for RF$Variable == Var1, if yes 
3) get RF$CO value, 
4) else return (0) 

我已經嘗試了兩種方法尚未:

METHOD 1: 
L1<- length(List1) 
y<-0 
DT1 <-DT1[,Score_CO:={for(i in 1:L1){ 
      x<-parse(text = List1[i]) 
      if(DT1[,eval(x)] == 1){ 
      x<-RF[which(RF[,'Variable'] == List1[i],),CO]} 
      else{as.numeric(0.0)} 
      y=y+x } 
      return(y)}] 

METHOD 2: 
Score_Calc<-function(DT,RF, List, model = 'CO'){ 
pvar<- 0 
pvar<-for(i in 1:nrow(DT)){ 
for(j in 1:length(List)){ 
    x<-parse(text = List[j]) 
    ifelse(DT[i,eval(x)] == 1, RF[which(RF[,'Variable'] == List[j],),model], 0) 
} 
pvar <- pvar + pvar 
DT[,paste0('Score_',model):= pvar] 
} 
return(DT) 
} 

Score_Calc(DT=DT1,RF = RF, List=List1, model = 'CO') 

但我沒有得到結果。輸出應該是:

OUTPUT: 
    id Var1 Var2 Var3 Var4 Var5 Score_CO 
    1 1 0 1 1 0 2.5 
    2 0 0 1 1 0 1.4 
    3 0 0 1 0 0 1.4 
    4 0 0 0 0 0 0 
    5 1 1 0 1 1 2.1 
    6 0 0 0 0 0 0 
    7 1 1 1 0 1 3.5 
    8 1 0 1 0 1 3.5 
    9 0 0 0 0 0 0 
    10 0 1 0 0 0 0 

P.S:Score_CO = VAR1 + VAR2 + VAR3(從RF表CO列中的值)

請看看,幫我找到我在做什麼錯。任何幫助表示讚賞。

回答

1

這裏是一個矩陣乘法版本:

as.matrix(DT1[, -1, with=F]) %*% as.matrix(RF[1:5, -1, with=F]) 
#  CO IN 
# [1,] 4.0 6.5 
# [2,] 2.9 4.4 
# [3,] 1.4 1.9 
# [4,] 0.0 0.0 
# [5,] 5.9 7.6 
# [6,] 0.0 0.0 
# [7,] 5.8 7.0 
# [8,] 3.5 5.7 
# [9,] 0.0 0.0 
# [10,] 2.3 1.3 

data.table第1版。只是要小心,一旦你設置RF關鍵,矩陣乘法會給你一個不同的答案設置鍵重新排序它

編輯:

setkey(RF, Variable) 
fun <- function(DT, col) sum(RF[names(DT), ][, col, with=F] * unlist(DT)) 
DT1[,list(CO=fun(.SD, "CO"), IN=fun(.SD, "IN")), by=id] 
#  id CO IN 
# 1: 1 4.0 6.5 
# 2: 2 2.9 4.4 
# 3: 3 1.4 1.9 
# 4: 4 0.0 0.0 
# 5: 5 5.9 7.6 
# 6: 6 0.0 0.0 
# 7: 7 5.8 7.0 
# 8: 8 3.5 5.7 
# 9: 9 0.0 0.0 
# 10: 10 2.3 1.3 
:,做兩種計算的備用3210

OLD VERSION:

這裏是計算CO的潛在解決方案。您可以輕鬆地將其擴展爲IN。基本上,我們做的是通過其相應的RF值乘以DT1的值,然後添加這些:通過在數據表中的每一Var#

setkey(RF, Variable) 
DT2 <- DT1[, c(
    list(id=id), 
    sapply(
    names(.SD[, -1, with=F]), 
    function(x) unlist(.SD[, x, with = F] * RF[x, ][, CO]), 
    simplify=F 
) 
) ][, CO:=apply(.SD[, -1, with=F], 1, sum)] 
DT2 
#  id Var1 Var2 Var3 Var4 Var5 CO 
# 1: 1 1.1 0.0 1.4 1.5 0 4.0 
# 2: 2 0.0 0.0 1.4 1.5 0 2.9 
# 3: 3 0.0 0.0 1.4 0.0 0 1.4 
# 4: 4 0.0 0.0 0.0 0.0 0 0.0 
# 5: 5 1.1 2.3 0.0 1.5 1 5.9 
# 6: 6 0.0 0.0 0.0 0.0 0 0.0 
# 7: 7 1.1 2.3 1.4 0.0 1 5.8 
# 8: 8 1.1 0.0 1.4 0.0 1 3.5 
# 9: 9 0.0 0.0 0.0 0.0 0 0.0 
# 10: 10 0.0 2.3 0.0 0.0 0 2.3 

第一sapply循環,尋找從CO中的相應值RF,並乘以該值的列(這會產生修改Var1-5值,你在上面看到,該CO:=apply(...位只計算Var1-5總和的每一行,並將其保存爲DT2一個CO列。

+0

由於它看起來不錯,我只是想 問我如何才能使用List1中的變量獲取DT1的子集。因爲對於CO,我只想檢查列表1(Var1,Var3,Var5)中的變量並添加它們。 – nsDataSci

+0

非常感謝,非常感謝。 – nsDataSci

+0

@nsDataSci,如果這回答你的問題,請考慮通過點擊複選框將其標記爲已回答。謝謝。 – BrodieG

相關問題