如何在组中查找NA并为数据框创建新列

时间:2014-01-14 16:02:30

标签: r aggregate na

我有一个由“ID”列和“Diff”列组成的数据框。 ID列负责标记相应Diff值的组。 一个例子如下:

structure(list(ID = c(566, 566, 789, 789, 789, 487, 487, 11, 
11, 189, 189), Diff = c(100, 277, 529, 43, NA, 860, 780, 445, 
NA, 578, 810)), .Names = c("ID", "Diff"), row.names = c(9L, 10L, 
20L, 21L, 22L, 25L, 26L, 51L, 52L, 62L, 63L), class = "data.frame")

我的目标是在Diff列中搜索每个组的NA,并创建一个新列,每列具有“True”或“False”值,具体取决于相应的组在Diff中是否具有NA。 / p>

我试过

x <- aggregate(Diff ~ ID, data, is.na)

y <- aggregate(Diff ~ ID, data, function(x) any(is.na(x)))

想法是根据ID合并结果。但是,以上都没有创造出有用的结果。我知道R可以做到......在搜索了一段时间之后我会问你怎么做:)

3 个答案:

答案 0 :(得分:2)

您可以使用plyrddply

require(plyr)
ddply(data, .(ID), transform, na_diff = any(is.na(Diff)))
##     ID Diff na_diff
## 1   11  445    TRUE
## 2   11   NA    TRUE
## 3  189  578   FALSE
## 4  189  810   FALSE
## 5  487  860   FALSE
## 6  487  780   FALSE
## 7  566  100   FALSE
## 8  566  277   FALSE
## 9  789  529    TRUE
## 10 789   43    TRUE
## 11 789   NA    TRUE

答案 1 :(得分:2)

base之外的@dickoa非常类似的解决方案:

do.call(rbind,by(data,data$ID,function(x)transform(x,na_diff=any(is.na(Diff)))))
#         ID Diff na_diff
# 11.51   11  445    TRUE
# 11.52   11   NA    TRUE
# 189.62 189  578   FALSE
# 189.63 189  810   FALSE
# 487.25 487  860   FALSE
# 487.26 487  780   FALSE
# 566.9  566  100   FALSE
# 566.10 566  277   FALSE
# 789.20 789  529    TRUE
# 789.21 789   43    TRUE
# 789.22 789   NA    TRUE

同样,你可以避免使用transform

data$na_diff<-with(data,by(Diff,ID,function(x) any(is.na(x)))[as.character(ID)])

答案 2 :(得分:1)

你已经有两个可行的策略了,但如果你对R相对较新并且不熟悉plyr的工作方式,那么另一个概念上可能更容易理解。

我经常需要知道我在不同变量中有多少NA,所以这里是一个使用标准的便利函数:

sna <- function(x){
  sum(is.na(x))
}

从那时起,我有时会使用aggregate(),但有时我会在?summaryBy包中找到doBy更方便。这是一个例子:

library(doBy)
z <- summaryBy(Diff~ID, data=my.data, FUN=sna)
z
   ID Diff.sna
1  11        1
2 189        0
3 487        0
4 566        0
5 789        1

在此之后,您只需使用?merge并将NA的计数转换为逻辑以获取最终数据框:

my.data          <- merge(my.data, z, by="ID")
my.data$Diff.sna <- my.data$Diff.sna>0
my.data
    ID Diff Diff.sna
1   11  445     TRUE
2   11   NA     TRUE
3  189  578    FALSE
4  189  810    FALSE
5  487  860    FALSE
6  487  780    FALSE
7  566  100    FALSE
8  566  277    FALSE
9  789  529     TRUE
10 789   43     TRUE
11 789   NA     TRUE