我有一个由“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可以做到......在搜索了一段时间之后我会问你怎么做:)
答案 0 :(得分:2)
您可以使用plyr
和ddply
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