2014-09-19 66 views
1

假設我有以下data.frameR:條件語句迭代相鄰列

>tmp 

    user  start.date  X03.16.2013 X03.17.2013 X03.18.2013 X03.19.2013 
    Allison 2013-03-15   5   5   0   2 
    Andrew 2013-03-15   2   0   0   0 
    Carl  2013-03-16   10   8   11   10 
    Dora  2013-03-16   5   4   0   0 
    Hilary 2013-03-17   NA   3   5   0 
    Louis  2013-03-18   NA   NA   8   3 
    Mary  2013-03-19   NA   NA   NA   7 
    Mickey 2013-03-20   NA   NA   NA   NA 

我想一個「死亡之日」分配給誰擁有兩個或更多天零個條目的用戶。我的方法是運行在列一個循環,並說:「如果tmp[x,j:j+1]之和等於零,則lastdateidtmp[x,j]x行」:

for (j in 3:dim(tmp)[2]){ 
    lastdateid <- apply(tmp, 1, function(x) { 
    i <- which(sum(tmp[x,j:j+1])==0); ifelse(length(i), head(i,1), NA) 
    }) 
} 

上述無限循環運行,也只是創建矢量lastdateid滿NA s。理想情況下,循環將返回安德魯的lastdateidtmp[2,4],多拉的爲tmp[4,5],其他人的值爲NA。什麼導致這個循環無限運行?我該如何解決這個問題呢?它給出了期望的結果?因爲我對R比較陌生,請耐心等待,謝謝!

回答

0

這可能會取代您的for循環。這是幾條線,但我相信它更有效率。

w <- which(t(apply(tmp == 0, 1, cumsum)) == 2, arr.ind = TRUE) 
w[,2] <- w[,2]-1 
rb <- rbind(w, matrix(, nrow(tmp)-nrow(w), ncol(w))) 
rownames(rb) <- tmp$user[c(x <- w[,2], seq_len(nrow(tmp))[-x])] 

其中給出的結果

> rb 
#   row col 
# Andrew 2 4 
# Dora  4 5 
# Allison NA NA 
# Carl  NA NA 
# Hilary NA NA 
# Louis NA NA 
# Mary  NA NA 
# Mickey NA NA 
+0

@理查德·斯克裏感謝您的解決方案。由於我仍然不熟悉使用'which()'和'apply'替換for循環,所以我想知道是否可以幫助我分解第一行。我知道'apply(tmp == 0,1,cumsum)'是在'tmp'行(用MARGIN = 1表示)上應用'cumsum'函數,但我不確定'which'知道在兩個相鄰列上運行cumsum(未來我希望能夠選擇多少個相鄰的單元格進行求和)。 – Archimeow 2014-09-22 17:40:01

+0

@JMeo當然。 'tmp == 0'將原始數據轉換爲邏輯矩陣。 't(應用(tmp == 0,1,cumsum)'在整行中運行'cumsum','== 2'用於找出第二次出現零的位置。 ,arr.ind = TRUE)'告訴我們第二次出現零的矩陣行和列索引。 – 2014-09-22 17:44:48

+0

@ Richard Scriven謝謝您花時間爲我解決這個問題,我仍然在學習如何最有效地學習使用'apply()'和'which()'代替循環。非常有幫助! – Archimeow 2014-09-24 18:14:51