2013-07-17 17 views
0

我試圖根據參考data.frame的值創建一個採用不同值的data.frame。我只知道如何用「for循環」來做到這一點,但建議避免R中的循環...並且我的實際數據有〜500,000行x〜200列。在沒有for循環的情況下在另一個df上創建data.frame條件

a <- as.data.frame(matrix(rbinom(10,1,0.5),5,2,dimnames=list(c(1:5),c("a","b")))) 
b <- data.frame(v1=c(2,10,12,5,11,3,4,14,2,13),v2=c("a","b","b","a","b","a","a","b","a","b")) 
c <- as.data.frame(matrix(0,5,2)) 

for (i in 1:5){ 
    for(j in 1:2){ 
    if(a[i,j]==1){ 
     c[i,j] <- mean(b$v1[b$v2==colnames(a)[j]]) 
    } else { 
     c[i,j]= mean(b$v1) 
    }}} 
c 

我基於data.frame「a」的每個單元格中的值和相應的列名稱創建data.frame「c」。 有沒有另一種方法來做到這一點?索引?使用data.table?也許適用功能? 任何和所有的幫助,非常感謝!

回答

1
(a == 0) * mean(b$v1) + t(t(a) * c(tapply(b$v1, b$v2, mean))) 

分段運行以瞭解發生了什麼。此外,請注意,這假定在a中有序的名稱(0和1作爲條目,按照OP)。

如上使用mapply一堆t的的另一種(假定adata.framedata.table而不是matrix,雖然上述不關心):

(a == 0) * mean(b$v1) + mapply(`*`, a, tapply(b$v1, b$v2, mean)) 
+0

我嘗試過,但結果與'c'不一樣。任何想法 ? – dickoa

+0

@dickoa謝謝,修復 – eddi

+0

@dickoa我有一種感覺,有一個更簡單的方法乘以這兩個,比上述 – eddi

1
#subsetting a matrix is faster 
res <- as.matrix(a) 

#calculate fill-in values outside the loop 
in1 <- mean(b$v1) 
in2 <- sapply(colnames(a),function(i) mean(b$v1[b$v2==i])) 

#loop over columns and use a vectorized approach 
for (i in seq_len(ncol(res))) { 
    res[,i] <- ifelse(res[,i]==0, in1, in2[i]) 
} 
+0

+1好方法,但'ifelse'被稱爲通常比傳統'if' ...'else'慢,但它看起來更加緊湊 – dickoa

+0

我不明白你的意見。 'ifelse'是矢量化的,'if'不是。 'ifelse'比'if'加一個循環要快。 – Roland

+0

你是對的,我很抱歉,如果向量化它的速度更快,但在非矢量化的情況下,它實際上更慢檢查http://stackoverflow.com/questions/8190279/is-ifelse-ever-appropriate-in-a-non-vectorized - 當然 - 反之亦然?rq = 1 – dickoa

相關問題