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

时间:2016-12-06 20:00:04

标签: r dplyr

我有一个数据框,其中我在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个标记。他们将被删除。虽然100001可能不是唯一的,但可能会重复使用不同的unique2值。

我要做的是使unique 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

2 个答案:

答案 0 :(得分:3)

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

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上进行冲突编辑。)

答案 1 :(得分:3)

您应该只使用Var := expression执行此操作。在这里,我dplyr,然后使用group_by返回该列中的任何值是否为&#34; 1&#34;。如果您的用例中有更复杂的条件,则可以在此处包含它们。

any

返回:

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)