我有一个像这样的数据框:
ID = c(1,1,1,2,2,2,3,3,3,4,4,4,4)
VAR_1 = c(2,4,6,1,7,9,4,4,3,1,7,4,0)
VAR_2 = c(NA,NA,NA,NA,NA,20190101,20190101,20190101,NA,20190101,NA,NA,NA)
df2 = data.frame(ID,VAR_1,VAR_2)
如果在VAR_2中按组的第一个观察值具有值,我想从此数据框中为每个组(ID)的所有行子集仅应该是ID的3和4中的所有行
为了更好地代表这一点:
df df_subset
ID VAR_1 VAR_2 ID VAR_1 VAR_2
1 2 NA 3 4 20190101
1 4 NA 3 4 20190101
1 6 NA 3 3 NA
2 1 NA 4 1 20190101
2 7 NA 4 7 NA
2 9 20190101 4 4 NA
3 4 20190101 4 0 NA
3 4 20190101
3 3 NA
4 1 20190101
4 7 NA
4 4 NA
4 0 NA
我设法分几个步骤进行操作(我仅按组对原始观察结果进行子集处理,将VAR_1分配一个特殊值,重新合并,然后最后按该特殊值进行过滤),但是我想知道有一种更简单,更优雅(也可能)更有效的方法。我不需要VAR_1,因此可以根据需要进行更改以提供更快的解决方案。
任何帮助将不胜感激。
答案 0 :(得分:2)
使用dplyr
,我们可以group_by
ID
并仅在每个组中的第一个值为非NA时选择组。
library(dplyr)
df2 %>%
group_by(ID) %>%
filter(!is.na(VAR_2[1L]))
# ID VAR_1 VAR_2
# <dbl> <dbl> <dbl>
#1 3 4 20190101
#2 3 4 20190101
#3 3 3 NA
#4 4 1 20190101
#5 4 7 NA
#6 4 4 NA
#7 4 0 NA
某些提取第一个值的方法可能是(感谢@tmfmnk)
df2 %>% group_by(ID) %>% filter(!is.na(first(VAR_2)))
OR
df2 %>% group_by(ID) %>% filter(!is.na(nth(VAR_2, 1)))
使用基数R ave
df2[with(df2, ave(!is.na(VAR_2), ID, FUN = function(x) x[1L])), ]
或带有split
和subset
的复杂
subset(df2, ID %in% names(na.omit(sapply(split(df2$VAR_2, df2$ID), head, 1))))