2012-06-04 77 views
2

假設我有一個7列的數據框,其中一些行有7個值,其他行有NAs通過某個點。我想抓住最後一個值(從左到右),它不是NA,然後是直接向左的值。這是分層數據,但有些羣體比其他羣體更深入。我想要在新數據框中的兩列中最深和最深的組。基於行中的NA在數據幀中選擇列

這段代碼可以工作,但是對於46K觀察的數據幀來說,我的記憶最大化了。有沒有更有效的方式我沒有想到?

df <- data.frame(LEVEL1 = c('animal', 'vegetable', 'mineral'), 
       LEVEL2 = c('mammal', 'pepper', 'rock'), 
       LEVEL3 = c('dog', 'jalepeno', NA), 
       LEVEL4 = c('westie', NA, NA)) 

deepest <- apply(df, 1, 
        function(x) length(which(!is.na(x)))) 
one.up <- apply(df, 1, 
        function(x) length(which(!is.na(x)))-1) 
len <- nrow(df) 
output <- data.frame(one.up = unlist(sapply(1:len, 
          function(x) df[x, one.up[x]])), 
        deepest= unlist(sapply(1:len, 
              function(x) df[x, deepest[x]]))) 

第一次發佈。通常我可以湊齊從我的網站需要的東西。提前致謝。

回答

3

我認爲你可以節省運行循環兩次,一個簡單的apply調用,如:

> apply(df, 1, function(x) { 
+  n <- max(which(!is.na(x))) 
+  x[(n-1):n] 
+ }) 
    [,1]  [,2]  [,3]  
[1,] "dog" "pepper" "mineral" 
[2,] "westie" "jalepeno" "rock" 
+0

這樣做。謝謝。 –

1

我不知道你的代碼將提供你認爲它應該如果NAS可以通過下面的長度穿插(儘管你說這不應該發生)。這段代碼將在第一個NA之前停止並返回兩個先前的值。

> output.m <- apply(df,1,function(x) { leng.na <-rle(is.na(x))$lengths[1] 
             tail(x[1:leng.na],2) } ) 
> output.d <- as.data.frame(t(output.m)) 
> output.d 
     V1  V2 
1  dog westie 
2 pepper jalepeno 
3 mineral  rock 
+0

謝謝了。我很確定我的數據沒有「內部」NAs,但我不知道這個功能。這會派上用場。 –