我对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中做到这一点?
答案 0 :(得分:1)
如果我正确理解了您的要求,这是使用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
答案 1 :(得分:0)
这是使用dplyr
执行此操作的方法。这会寻找所有ID
+ Date
组合,每个组合的输入和输出均至少个。
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
答案 2 :(得分:0)
出于完整性考虑,以下是一些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
组中,仅返回df
的那些子集,其中有多个不同的Type
。
这也可以写成:
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)