在data.frame中按组删除尾随NA

问题描述 投票:4回答:2

我有一个带有分组变量的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)

r dataframe dplyr na zoo
2个回答
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

或者使用by,如@Henrik所述:

do.call("rbind", by(df, df$group, na.trim, sides = "right"))

5
投票

你可以编写一个小辅助函数,检查向量的尾随NAs,然后使用group_byfilter

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
© www.soinside.com 2019 - 2024. All rights reserved.