2015-12-03 73 views
2

我想了解如何根據條件來處理數據幀的行。 有這樣R - 根據條件對數據幀行進行操作

> d<-data.frame(x=c(0,1,2,3), y=c(1,1,1,0)) 
> d 
    x y 
1 0 1 
2 1 1 
3 2 1 
4 3 0 

數據幀如何添加+1到包含零值的所有行? (請注意,零點可在任一列中找到),這樣的結果是這樣的:

x y 
1 1 2 
2 1 1 
3 2 1 
4 4 1 

下面的代碼似乎做這項工作的一部分,但只是打印拍攝該行動的行,次數就被帶到(2)...

> for(i in 1:nrow(d)){ 
+  d[d[i,]==0,]<-d[i,]+1 
+ } 
> d 
    x y 
1 1 2 
2 4 1 
3 1 2 
4 4 1 

我敢肯定有這一個簡單的解決方案,也許一個應用函數?但我沒有到達那裏。

謝謝。

+0

您是否需要單獨顯示已更改的行,還需要在添加1之前還是之後顯示它?如果它之前我可以寫一個簡單的代碼! –

回答

2

一些可能性:

# 1 
idx <- which(d == 0, arr.ind = TRUE)[, 1] 
d[idx, ] <- d[idx, ] + 1 
# 2 
t(apply(d, 1, function(x) x + any(x == 0))) 
# 3 
d + apply(d == 0, 1, max) 

which的爲載體的使用,例如which(1:3 > 2),是相當普遍的,而它的基質中使用較少:通過指定arr.ind = TRUE我們得到的是數組下標,即每一個0座標:

which(d == 0, arr.ind = TRUE) 
    row col 
[1,] 1 1 
[2,] 4 2 

因爲我們在那裏的零發生感興趣的只是行,我走第一列which(d == 0, arr.ind = TRUE),並將這些行中的所有元素加上d[idx, ] <- d[idx, ] + 1

關於第二種方法,apply(d, 1, function(x) x)只是簡單地逐行進行,並且沒有任何修改就返回相同的行。通過any(x == 0)我們檢查一個特定行中是否有零,並得到TRUEFALSE。但是,通過編寫x + any(x == 0),我們根據需要分別將TRUEFALSE轉換爲1或0。

現在是第三種方法。 d == 0是一個邏輯矩陣,我們使用apply來遍歷它的行。然後,當將max應用於特定行時,我們再次將TRUE,FALSE轉換爲1,0並找到最大元素。當且僅當該行中有零時,該元素爲1。因此,apply(d == 0, 1, max)返回一個零和一個向量。最後一點是,當我們編寫A + b時,其中A是一個矩陣,而b是一個向量,添加是列式的。通過這種方式,通過編寫d + apply(d == 0, 1, max),我們將apply(d == 0, 1, max)添加到d的每一列,根據需要。

+0

好的,所以答案並不那麼簡單(至少對我來說......)。你能詳細說明每個功能嗎? – PedroA

+0

@PedroA,當然,我會盡快更新我的答案。 – Julius

+1

@PedroA爲了簡單起見,我建議'idx = d $ x == 0 | d $ y == 0; d [idx,] = d [idx,] + 1'。它與選項1類似,但是,我覺得它更清潔一些。海事組織,我只會考慮選項1.方案2和3雖然很聰明,但對於較大的矩陣可能會比方案1慢。一般來說,最好在可能的情況下使用子設置而不是迭代來處理R問題。 –