0

我有一个 R 数据框,其中包含来自多个主题的数据,每个主题都测试了几次。为了对集合进行统计,有一个主题(“id”)的因子和每个观察的一行(由因子“会话”给出)。IE

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”列在 id==2 的行之一中包含 NA?

更一般地说,由于我实际上为每个主题有很多度量(列)和四个会话(行),有没有一种优雅的方法来删除具有给定“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,]

谢谢,/乔纳斯

4

2 回答 2

3

您可以使用包中的ddply函数plyr来 1) 通过 对数据进行子集化id,2) 应用一个函数,NULL如果子 data.frame 包含NA在您选择的列中,或者 data.frame 本身包含在您选择的列中,则该函数将返回,以及 3) 连接一切都回到data.frame。

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
于 2012-03-29T00:18:11.387 回答
0

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

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

这是仅使用基本包的正确版本。只是为了好玩。:) 但它既不紧凑也不简单。弗洛德尔的回答更整洁。甚至您的初始解决方案也更紧凑,我认为更快。

cleanedData <- do.call(rbind, sapply(unique(allData[,"id"]), function(x) {if(all(!is.na(allData[allData$id==x, probeColumn]))) allData[allData$id==x,]}))
于 2012-03-28T12:25:32.450 回答