我有一个数据帧,其中的 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)
。