r语言 - 子集数据框,仅包含一个因子的水平,且该因子在另一个因子的两个水平中都具有值



我正在使用一个处理数字测量的数据框。有些人已经被测量了几次,无论是青少年还是成年人。 一个可重现的示例:

ID <- c("a1", "a2", "a3", "a4", "a1", "a2", "a5", "a6", "a1", "a3")
age <- rep(c("juvenile", "adult"), each=5)
size <- rnorm(10)
# e.g. a1 is measured 3 times, twice as a juvenile, once as an adult.
d <- data.frame(ID, age, size)

我的目标是通过选择至少作为青少年出现一次和作为成年人至少出现一次的 ID 来子集该数据框。不知道该怎么做..?

生成的数据帧将包含个体 a1、a2 和 a3 的所有测量值,但将排除 a4、a5 和 a6,因为它们不是在两个阶段测量的。

7 个月前有人问过一个类似的问题,但从未得到答案(子集数据框仅包括水平一个因子,在另一个因子的两个水平中都有值(

谢谢!

使用dplyr,您可以使用group_by %>% filter

library(dplyr)
d %>% group_by(ID) %>% filter(all(c("juvenile", "adult") %in% age))
# A tibble: 7 x 3
# Groups:   ID [3]
#      ID      age       size
#  <fctr>   <fctr>      <dbl>
#1     a1 juvenile -0.6947697
#2     a2 juvenile -0.3665272
#3     a3 juvenile  1.0293555
#4     a1 juvenile  0.2745224
#5     a2    adult  0.5299029
#6     a1    adult  2.2247802
#7     a3    adult -0.4717160

ageintersect和子集split

d[d$ID %in% Reduce(intersect, split(d$ID, d$age)),]
#   ID      age        size
#1  a1 juvenile  1.44761836
#2  a2 juvenile  1.70098645
#3  a3 juvenile  0.08231986
#5  a1 juvenile  0.91240568
#6  a2    adult -1.77318962
#9  a1    adult  0.13597986
#10 a3    adult -1.18575294

这是一个带有data.table的选项

library(data.table)
setDT(d)[, .SD[all(c("juvenile", "adult") %in% age)], ID]

或者带有avebase R选项

d[with(d, ave(as.character(age), ID, FUN = function(x) length(unique(x)))>1),]
#   ID      age       size
#1  a1 juvenile -1.4545407
#2  a2 juvenile -0.4695317
#3  a3 juvenile  0.2271316
#5  a1 juvenile  0.2961210
#6  a2    adult -0.8331993
#9  a1    adult -0.6924967
#10 a3    adult -0.4619550