r语言 - 如果整个组满足条件,如何仅保留 data.frame 的那些行



我对R相当陌生,我有一个关于如何仅保留基于ID和日期的某些值的问题。我有一个(相当大的(数据集,类似于以下示例:

ID Type Date
1  OUT 2016-06-18
1  OUT 2016-06-18
1  OUT 2016-06-18
1  IN  2016-06-25
1  OUT 2016-06-25
2  IN  2016-07-03
2  OUT 2016-07-03

我现在的问题是,如何找到仅包含一种类型(IN 或 OUT(的日期并从数据中删除它们。但是,如果类型是一对(IN 和 OUT(并且 ID 值相同,我想保留日期。

有没有办法在 R 中做到这一点?

如果我正确理解了您的要求,这里有一种使用dplyr包的简单方法 -

df %>%
group_by(ID, Date) %>%
filter(n_distinct(Type) > 1)
# A tibble: 4 x 3
# Groups:   ID, Date [2]
ID Type  Date      
<int> <chr> <chr>     
1     1 IN    2016-06-25
2     1 OUT   2016-06-25
3     2 IN    2016-07-03
4     2 OUT   2016-07-03

使用基数 R 中的ave()的另一种方法 -

df[with(df, ave(Type, ID, Date, FUN = function(x) length(unique(x)))) == 2, ]
ID Type       Date
4  1   IN 2016-06-25
5  1  OUT 2016-06-25
6  2   IN 2016-07-03
7  2  OUT 2016-07-03

这是使用dplyr执行此操作的一种方法。这将查找所有ID+Date组合,这些组合至少有一个 In和Out。

has_both <- df1 %>%
count(ID, Date, Type) %>%  # How many rows with each combo ID / Date / Type
count(ID, Date) %>% # How many rows appear for each ID / Date
filter(nn == 2) %>% # Only keep where 2 types (IN and OUT, presumably)
left_join(df1)  %>% # Bring back matching original data

输出

has_both
# A tibble: 4 x 4
ID Date          nn Type 
<int> <chr>      <int> <chr>
1     1 2016-06-25     2 IN   
2     1 2016-06-25     2 OUT  
3     2 2016-07-03     2 IN   
4     2 2016-07-03     2 OUT 

为了完整起见,这里还有一些 data.table 解决方案:

library(data.table)
setDT(df)[, if (uniqueN(Type) > 1) .SD, by = .(ID, Date)]
ID       Date Type
1:  1 2016-06-25   IN
2:  1 2016-06-25  OUT
3:  2 2016-07-03   IN
4:  2 2016-07-03  OUT

在每个ID中,Date分组时只返回那些有多个不同Typedf子集。


这也可以写成:

setDT(df)[, .SD[uniqueN(Type) > 1], by = .(ID, Date)]

还有一个变体,它找到满足要求的IDDate组合,并通过连接df子集:

setDT(df)[df[, uniqueN(Type), by = .(ID, Date)][V1 > 1], on = .(ID, Date), .SD]
ID Type       Date
1:  1   IN 2016-06-25
2:  1  OUT 2016-06-25
3:  2   IN 2016-07-03
4:  2  OUT 2016-07-03
<小时 />

数据

df <-readr::read_delim(
"ID Type Date
1  OUT 2016-06-18
1  OUT 2016-06-18
1  OUT 2016-06-18
1  IN  2016-06-25
1  OUT 2016-06-25
2  IN  2016-07-03
2  OUT 2016-07-03", 
delim = " ", trim_ws = TRUE)

相关内容

最新更新