2013-06-19 71 views
0

我有一個數據框,我想重新塑造它,以便每個觀察obs只有一行。下面是示例數據:聚合數據框並刪除不適用

data <- data.frame("obs" = c('1','1','1','2','2'), 
        "value1" = c(1,NA,NA,NA,NA), 
        "value2" = c(NA,NA,3,1,NA), 
        "value3" = c(NA,2,NA,NA,5)) 

數據是這樣的:

obs value1 value2 value3 
    1  1  NA  NA 
    1  NA  NA  2 
    1  NA  3  NA 
    2  NA  1  NA 
    2  NA  NA  5 

,我想它重塑爲:

obs value1 value2 value3 
1  1  3  2 
2  NA  1  5 

謝謝!

+4

你可以肯定,你將永遠不會有相同的OB和給定值列中輸入兩行?如果是這樣,喬蘭的答案很好。否則,如果每個'obs'值只需要一行,就必須決定如何處理它們。 – Justin

+0

你說得對。現在我使用了Joran的代碼,我發現對於某些obs代碼,我有額外的值。在這種情況下,我怎麼能得到這些值的意思是每個obs只有一行? –

+0

您可以修改其函數的第二行('else'語句),以返回「mean(x [!is.na(x)])'。 – Justin

回答

2

這是我會怎麼做,用plyr

foo <- function(x){ 
    if (all(is.na(x))) return(NA) 
    else return(x[!is.na(x)]) 
} 

ddply(dat,.(obs),colwise(foo)) 

這當然假定你確實只能有至多一個非NA值在每列的obs每個值。

如果不是這種情況,並且要採取多個值的平均值,你可以嘗試做賈斯汀建議:

mean(x[!is.na(x)]) 
4
library(data.table) 
dt = data.table(dat) 

dt[, lapply(.SD, function(x) x[!is.na(x)]), by = obs] 

如果每個值的多個條目的根據觀察,這將使用R的回收邏輯來填補其餘部分。

2

底液:

out <- lapply(split(data, data$obs), function(x) { 
    ans <- lapply(x[, -1], na.omit) 
    data.frame(obs = x[1, 1], t(sapply(ans, "[", 1))) 
}) 

do.call(rbind, out) 

## > do.call(rbind, out) 
## obs value1 value2 value3 
## 1 1  1  3  2 
## 2 2  NA  1  5