我有一个带有分组变量的data.frame,并且在值列中有一些NA。
df = data.frame(group=c(1,1,2,2,2,2,2,3,3), value1=1:9, value2=c(NA,4,9,6,2,NA,NA,1,NA))
我可以使用zoo::na.trim
删除列末尾的NA:这将删除data.frame的最后一行:
library(zoo)
library(dplyr)
df %>% na.trim(sides="right")
现在,我想按组删除尾随的NA;如何使用dplyr做到这一点?
value2 列的预期输出:c(NA, 4,9,6,2,1)
答案 0 :(得分:4)
您可以编写一个小的辅助函数,以检查向量的尾随NA
,然后使用group_by
和filter
。
f <- function(x) { rev(cumsum(!is.na(rev(x)))) != 0 }
library(dplyr)
df %>%
group_by(group) %>%
filter(f(value2))
# A tibble: 6 x 3
# Groups: group [3]
group value1 value2
<dbl> <int> <dbl>
1 1 1 NA
2 1 2 4
3 2 3 9
4 2 4 6
5 2 5 2
6 3 8 1
修改
如果我们需要同时删除前导零和尾随零,则需要对该函数进行一些扩展。
f1 <- function(x) { cumsum(!is.na(x)) != 0 & rev(cumsum(!is.na(rev(x)))) != 0 }
给出df1
df1 = data.frame(group=c(1,1,2,2,2,2,2,3,3), value1=1:9, value2=c(NA,4,9,NA,2,NA,NA,1,NA))
df1
# group value1 value2
#1 1 1 NA
#2 1 2 4
#3 2 3 9
#4 2 4 NA
#5 2 5 2
#6 2 6 NA
#7 2 7 NA
#8 3 8 1
#9 3 9 NA
我们得到这个结果
df1 %>%
group_by(group) %>%
filter(f1(value2))
# A tibble: 5 x 3
# Groups: group [3]
group value1 value2
<dbl> <int> <dbl>
1 1 2 4
2 2 3 9
3 2 4 NA
4 2 5 2
5 3 8 1
答案 1 :(得分:3)
使用 lapply ,遍历组:
do.call("rbind", lapply(split(df, df$group), na.trim, sides = "right"))
# group value1 value2
# 1.1 1 1 NA
# 1.2 1 2 4
# 2.3 2 3 9
# 2.4 2 4 6
# 2.5 2 5 2
# 3 3 8 1
或使用{em> by ,如@Henrik所述:
do.call("rbind", by(df, df$group, na.trim, sides = "right"))