2012-09-17 51 views
1
Col1<-c(3,8,2,4,2) 
Col2<-c(3,7,3,9,2) 
Col3<-c(5,7,5,7,5) 
Col4<-c(1,9,2,3,4) 
Col5<-c(1,2,6,7,5) 
Toy<-data.frame(Col1,Col2,Col3,Col4,Col5) 

> Toy 
    Col1 Col2 Col3 Col4 Col5 
1 3 3 5 1 1 
2 8 7 7 9 2 
3 2 3 5 2 6 
4 4 9 7 3 7 
5 2 2 5 4 5 

鑑於上述數據幀中,我想發生,以除去在每行中是等於每行的最大值的值,以及在正確的(或增加列號)的最大值。如何降基於所述最大值列各行

從邏輯上講,語句應該是:

1. Find max value per row 
2. Make max value for each row = NA 
3. Make all columns to the right of column with max value =NA 

所以新的數據幀將看起來像

Col1 Col2 Col3 Col4 Col5 
1 3 3 NA NA NA 
2 8 7 7 NA NA 
3 2 3 5 2 NA 
4 4 NA NA NA NA 
5 2 2 NA NA NA 

步驟

+0

抱歉,因爲這是我不認爲這是一個非常好的問題。如果您通過提供的解決方案閱讀[到您以前的問題](http://stackoverflow.com/questions/12449377/simple-use-of-if-and-for)並試圖理解爲什麼選擇它們的邏輯,你會發現[Josh O'Brien的很好的答案](http://stackoverflow.com/a/12453666/1270695)可以很容易地從你以前的問題的另一個答案派生出來。 – A5C1D2H2I1M1N2O1R2T1

+0

同意。在我問這個問題之前,我沒有意識到「which.max」命令,這讓我很難過。一如既往,感謝每個人的投入。 – Vinterwoo

回答

11

下面是一個apply()基於解決方案,避免了明確的for循環:

ff <- function(X) {X[which.max(X):length(X)] <- NA; X} 
t(apply(Toy, 1, ff)) 
#  Col1 Col2 Col3 Col4 Col5 
# [1,] 3 3 NA NA NA 
# [2,] 8 7 7 NA NA 
# [3,] 2 3 5 2 NA 
# [4,] 4 NA NA NA NA 
# [5,] 2 2 NA NA NA 
+0

+1,它避免了全局分配。 –

+0

@Josh很好! +1 –

2

首先,我們需要找到最大值爲指數每行,並構建一個矢量,該索引的索引到該行的末尾。我們想用一個應用循環來做到這一點每行:

list_of_indices = apply(Toy, 1, function(x) which.max(x):ncol(Toy)) 
> list_of_indices 
[[1]] 
[1] 3 4 5 

[[2]] 
[1] 4 5 

[[3]] 
[1] 5 

[[4]] 
[1] 2 3 4 5 

[[5]] 
[1] 3 4 5 

那麼我們就可以索引列表的循環,並在data.frame分配NA到適當的地方:

for(i in seq_along(list_of_indices)) { 
    Toy[i,list_of_indices[[i]]] <- NA 
} 

這導致期望的結果:

> Toy 
    Col1 Col2 Col3 Col4 Col5 
1 3 3 NA NA NA 
2 8 7 7 NA NA 
3 2 3 5 2 NA 
4 4 NA NA NA NA 
5 2 2 NA NA NA 
2

的lapply方法(保羅一分鐘打我):

inds <- lapply(apply(Toy, 1, which.max), function(x) x:ncol(Toy)) 
lapply(1:nrow(Toy), function(i) {Toy[i, inds[[i]]] <<- NA; return(Toy)}) 
Toy 
+0

+1,但我寧願使用for循環來堅持需要全局賦值的'apply'基礎解決方案('<< - ')。 –

+0

@Paul我同意,但因爲R是我的第一語言,所以我的大腦總是進入應用解決方案而不是循環。如果我們進行了基準測試,我敢打賭你的速度會更快,因爲我相信'lapply'只是for循環的一個包裝。 –

+0

必須使用'apply',一定不要使用'for','for'是邪惡的! ;) –