按 R 中的标志指示符删除行组



我有一个数据帧,其中的 unique3 列中有一组数字。

structure(list(unique1 = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L), .Label = c("11/1/2016", "11/10/2016", "11/11/2016", 
"11/12/2016", "11/13/2016", "11/14/2016", "11/15/2016", "11/16/2016", 
"11/17/2016", "11/18/2016", "11/19/2016", "11/2/2016", "11/20/2016", 
"11/21/2016", "11/22/2016", "11/23/2016", "11/24/2016", "11/25/2016", 
"11/26/2016", "11/27/2016", "11/28/2016", "11/3/2016", "11/4/2016", 
"11/5/2016", "11/6/2016", "11/7/2016", "11/8/2016", "11/9/2016"
), 
class = "factor"), unique2 = c(21L, 21L, 21L, 21L, 21L, 21L, 
21L, 21L, 31L, 41L), unique3 = c(100001L, 100001L, 100001L, 100001L, 
100001L, 100001L, 100001L, 100001L, 100002L, 100003L), 
flag = c(NA_integer_,1, NA_integer_, NA_integer_, NA_integer_, NA_integer_, 
NA_integer_, NA_integer_, NA_integer_, NA_integer_), value = c(1L, 
                6L, 18L, 19L, 22L, 29L, 30L, 32L, 1L, 1L)), 
.Names = c("unique1","unique2", "unique3", "flag", "value"), row.names = c(NA, 10L), class = "data.frame")
unique1 unique2 unique3 flag value
1  11/1/2016      21  100001   NA     1
2  11/1/2016      21  100001    1     6
3  11/1/2016      21  100001   NA    18
4  11/1/2016      21  100001   NA    19
5  11/1/2016      21  100001   NA    22
6  11/1/2016      21  100001   NA    29
7  11/1/2016      21  100001   NA    30
8  11/1/2016      21  100001   NA    32
9  11/1/2016      31  100002   NA     1
10 11/1/2016      41  100003   NA     1

我基本上需要按唯一的第 3 列分组,其中如果 100001 的任何行都有 1 in 标志。它们将被移除。尽管100001可能不是唯一的,并且可能会重复不同的 unique2 值。

我要做的是使唯一 3 的所有值都具有 1 的值,如下所示

unique1 unique2 unique3 flag value
1  11/1/2016      21  100001   1     1
2  11/1/2016      21  100001   1     6
3  11/1/2016      21  100001   1    18
4  11/1/2016      21  100001   1    19
5  11/1/2016      21  100001   1    22
6  11/1/2016      21  100001   1    29
7  11/1/2016      21  100001   1    30
8  11/1/2016      21  100001   1    32
9  11/1/2016      31  100002   NA     1
10 11/1/2016      41  100003   NA     1

然后分组依据并筛选为:

unique1 unique2 unique3 flag value
1  11/1/2016      21  100001   1     1
2  11/1/2016      21  100001   1     6
3  11/1/2016      21  100001   1    18
4  11/1/2016      21  100001   1    19
5  11/1/2016      21  100001   1    22
6  11/1/2016      21  100001   1    29
7  11/1/2016      21  100001   1    30
8  11/1/2016      21  100001   1    32

第一步(将标志统一应用于每个组):

DF$flag <- ave(DF$flag, DF$unique3, FUN = function(x) max(c(0,x), na.rm=TRUE))

然后,您可以过滤几种不同的方式。一种选择是:

subset(DF, flag == 1)

工作原理

ave(v, g1, g2, g3, FUN = f)根据分组变量拆分向量v;对每个子向量应用一个函数;重新组合以返回与v类相同的向量。

max(c(0,x), na.rm=TRUE)删除 NA 值,添加一个 0 值,然后取最大值。如果x仅包含 1 和 NA,则x包含任何 1 时返回 1,否则返回 0。


一些带有软件包的替代方案

library(data.table)
DT = setDT(copy(DF))
DT[, flag := max(c(0,flag), na.rm=TRUE), by=unique3][ flag == 1 ] 
# or...
library(dplyr)
DF2 = DF
(DF2 %<>% 
group_by(unique3) %>% 
mutate(flag = max(c(0,flag), na.rm=TRUE))
) %>% filter(flag == 1)

(我在这里只创建 DF2 和 DT 对象,以便可以直接运行代码,而不会在 DF 上进行冲突编辑。

您应该只需dplyr就可以做到这一点。在这里,我group_by,然后使用any返回该列中的任何值是否为"1"。如果您的用例中有更复杂的条件,则可以在此处包含它们。

df %>%
group_by(unique3) %>%
mutate(newFlag = any(flag == 1, na.rm = TRUE))

返回:

unique1 unique2 unique3  flag value newFlag
<fctr>   <int>   <int> <dbl> <int>   <lgl>
1  11/1/2016      21  100001    NA     1    TRUE
2  11/1/2016      21  100001     1     6    TRUE
3  11/1/2016      21  100001    NA    18    TRUE
4  11/1/2016      21  100001    NA    19    TRUE
5  11/1/2016      21  100001    NA    22    TRUE
6  11/1/2016      21  100001    NA    29    TRUE
7  11/1/2016      21  100001    NA    30    TRUE
8  11/1/2016      21  100001    NA    32    TRUE
9  11/1/2016      31  100002    NA     1   FALSE
10 11/1/2016      41  100003    NA     1   FALSE

专栏newFlag完成了我认为您的要求。如果您愿意,可以改为覆盖flag

您可以使用它进行如下过滤:

df %>%
group_by(unique3) %>%
mutate(newFlag = any(flag == 1, na.rm = TRUE)) %>%
filter(newFlag)

从您的问题来看,目前尚不清楚您是要保留还是丢弃具有标志的组。如果要删除它们,请改用filter(!newFlag)。无论哪种情况,如果要在筛选后删除新列,请使用select(-newFlag)

最新更新