r - 如何在R中按组删除前导和尾随NA的行
问题描述
我需要删除包含 NA 的行,但前提是它们是前导(尾随),即之前(之后)出现变量的任何数据。这非常类似于: 如何在 data.table 列中按类别查找(而不是替换)前导 NA、间隙和最终 NA, 以及: 如何在 R 中按条件删除前导行和尾随行?
但是,我需要按变量“ID”分组执行此过程。我将在后面的步骤中估算介于两者之间的 NA 数据。
这同样适用于尾随的 NA。
初始 data.frame 如下所示:
df1<-data.frame(ID=(rep(c("C1001","C1008","C1009","C1012"),each=17)),
Year=(rep(c(1996:2012),4)),x1=(floor(runif(68,20,75))),x2=
(floor(runif(68,1,100))))
#Introduce leading / tailing NAs
df1[1:5,3]<-NA
df1[18:23,4]<-NA
df1[35:42,4]<-NA
df1[49:51,3]<-NA
df1[66:68,3]<-NA
#introduce "gap"- NAs
set.seed(123)
df1$x1[rbinom(68,1,0.1)==1]<-NA
df1$x2[rbinom(68,1,0.1)==1]<-NA
输出很长。这是为了在“间隙”-NA 和“领先/尾随” NA 之间做出适当的区分
head(df1,10)
ID Year x1 x2
1 C1001 1996 NA 40
2 C1001 1997 NA 88
3 C1001 1998 NA 37
4 C1001 1999 NA 29
5 C1001 2000 NA 17
6 C1001 2001 42 18
7 C1001 2002 20 48
8 C1001 2003 30 26
9 C1001 2004 66 22
10 C1001 2005 32 67
输出应按 ID 组去除领先的 NA(参见上面的第 1:5 行)。或以下示例中的第 18:23 行:
df1[18:28,]
ID Year x1 x2
18 C1008 1996 33 NA
19 C1008 1997 26 NA
20 C1008 1998 NA NA
21 C1008 1999 51 NA
22 C1008 2000 31 NA
23 C1008 2001 44 NA
24 C1008 2002 NA 56
25 C1008 2003 47 70
26 C1008 2004 39 91
27 C1008 2005 55 62
28 C1008 2006 40 43
最终输出应该是这样的(当然取决于抛出的随机 NA!):
ID Year x1 x2
6 C1001 2001 42 18
7 C1001 2002 20 48
8 C1001 2003 30 26
9 C1001 2004 66 22
10 C1001 2005 32 67
11 C1001 2006 NA 5
12 C1001 2007 24 70
13 C1001 2008 33 35
14 C1001 2009 60 41
15 C1001 2010 66 82
16 C1001 2011 47 91
17 C1001 2012 41 28
24 C1008 2002 NA 56
25 C1008 2003 47 70
26 C1008 2004 39 91
27 C1008 2005 55 62
28 C1008 2006 40 43
29 C1008 2007 39 54
30 C1008 2008 49 6
31 C1008 2009 NA 26
32 C1008 2010 NA 40
33 C1008 2011 42 20
34 C1008 2012 34 83
44 C1009 2005 51 96
45 C1009 2006 66 96
46 C1009 2007 37 NA
47 C1009 2008 58 26
48 C1009 2009 34 22
52 C1012 1996 51 78
53 C1012 1997 70 17
54 C1012 1998 69 41
55 C1012 1999 35 47
56 C1012 2000 37 86
57 C1012 2001 74 92
58 C1012 2002 54 NA
59 C1012 2003 71 67
60 C1012 2004 45 95
61 C1012 2005 42 52
62 C1012 2006 56 58
63 C1012 2007 28 34
64 C1012 2008 51 35
65 C1012 2009 33 2
非常感谢!
解决方案
这是一种方法,它使用相同的想法filter_at()
来识别前导NA
值和尾随值,但向量相反。cumsum()
library(dplyr)
df1 %>%
group_by(ID) %>%
filter_at(vars(-ID, -Year), all_vars(pmin(cumsum(!is.na(.)), rev(cumsum(!is.na(rev(.))))) != 0))
# A tibble: 42 x 4
# Groups: ID [4]
ID Year x1 x2
<fct> <int> <dbl> <dbl>
1 C1001 2001 42 18
2 C1001 2002 20 48
3 C1001 2003 30 26
4 C1001 2004 66 22
5 C1001 2005 32 67
6 C1001 2006 NA 5
7 C1001 2007 24 70
8 C1001 2008 33 35
9 C1001 2009 60 41
10 C1001 2010 66 82
# ... with 32 more rows
推荐阅读
- c++ - 调用 EXPECT_CALL 时 GTest 失败
- python - 如何为此作业编写蛮力算法?
- flutter - image_picker 在构建中抛出异常
- coldfusion - 在 ColdFusion 2018 中创建报告失败
- bash - 检查 csv 字段的文本大小并转换为字节
- jenkins - Jenkins Pipeline ssh 步骤 sshPut 所有文件类型
- php - phpseclib - 带有 rsa 密钥的 sftp 登录失败
- angular - Angular RXHJ 映射多个对象属性
- python - 如何打印出购物清单中某件商品的单独价格
- javascript - 向上和向下箭头不适用于 JavaScript 中的 onkeydown