我对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
分组时只返回那些有多个不同Type
的df
子集。
这也可以写成:
setDT(df)[, .SD[uniqueN(Type) > 1], by = .(ID, Date)]
还有一个变体,它找到满足要求的ID
和Date
组合,并通过连接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)