R:根据较少行中的缺失值删除多行

时间:2012-03-28 11:47:00

标签: r missing-data anova

我有一个R数据框,其中包含来自多个科目的数据,每个都经过多次测试。要对集合执行统计,主题(“id”)的因子和每个观察的行(由因子“session”给出)。即。

print(allData)
id     session     measure
1      1           7.6
2      1           4.5
3      1           5.5
1      2           7.1
2      2           NA
3      2           4.9

在上面的示例中,是否有一种简单的方法可以删除id == 2的所有行,前提是“measure”列在其中一行中包含NA,其中id == 2?

更一般地说,因为我实际上为每个主题都有很多度量(列)和四个会话(行),所以有一种优雅的方法来删除具有给定级别的“id”因子的所有行,给定(至少)其中一个具有此“id”级别的行在列中包含NA?

我有直觉认为可能有一个内置函数可以比我目前的解决方案更优雅地解决这个问题:

# Which columns to check for NA's in
probeColumns = c('measure1','measure4') # Etc...

# A vector which contains all levels of "id" that are present in rows with NA's in the probeColumns
idsWithNAs = allData[complete.cases(allData[probeColumns])==FALSE,"id"]

# All rows that isn't in idsWithNAs
cleanedData = allData[!allData$id %in% idsWithNAs,]

谢谢, /乔纳斯

2 个答案:

答案 0 :(得分:3)

您可以ddply使用plyr包中的id功能对1)数据进行子集化,NULL,2) 如果子data.frame在您选择的列中包含NA,则应用将返回allData <- data.frame(id = rep(1:4, 3), session = rep(1:3, each = 4), measure1 = sample(c(NA, 1:11)), measure2 = sample(c(NA, 1:11)), measure3 = sample(c(NA, 1:11)), measure4 = sample(c(NA, 1:11))) allData # id session measure1 measure2 measure3 measure4 # 1 1 1 3 7 10 6 # 2 2 1 4 4 9 9 # 3 3 1 6 6 7 10 # 4 4 1 1 5 2 3 # 5 1 2 NA NA 5 11 # 6 2 2 7 10 6 5 # 7 3 2 9 8 4 2 # 8 4 2 2 9 1 7 # 9 1 3 5 1 3 8 # 10 2 3 8 3 8 1 # 11 3 3 11 11 11 4 # 12 4 3 10 2 NA NA # Which columns to check for NA's in probeColumns = c('measure1','measure4') library(plyr) ddply(allData, "id", function(df)if(any(is.na(df[, probeColumns]))) NULL else df) # id session measure1 measure2 measure3 measure4 # 1 2 1 4 4 9 9 # 2 2 2 7 10 6 5 # 3 2 3 8 3 8 1 # 4 3 1 6 6 7 10 # 5 3 2 9 8 4 2 # 6 3 3 11 11 11 4 的函数,否则返回data.frame本身,以及3)将所有内容连接回data.frame。

{{1}}

答案 1 :(得分:0)

使用你的例子,它的两个最后命令可以在这样的字符串中转换。它应该产生相同的结果,看起来更简单。

cleanedData <- allData[complete.cases(allData[,probeColumns]),]

这是一个只使用基础包的正确版本。纯娱乐。 :)但它既不紧凑也不简单。 flodel的答案更整洁。即使您的初始解决方案更紧凑,我认为更快。

cleanedData <- do.call(rbind, sapply(unique(allData[,"id"]), function(x) {if(all(!is.na(allData[allData$id==x, probeColumn]))) allData[allData$id==x,]}))