删除两对重复的案例

时间:2018-04-10 09:46:53

标签: r distinct

我的数据集中包含一些模糊的结束日期。由于我无法确定哪一个是正确的,我想将它们从数据框中删除,但无法弄明白。

以下是df示例:

ID = as.integer(c(1,1,2,2,2,3,3,4,5,5,6,6))
Feature = c("A","A","A","A","A","A","B","B","B","B","B","C")
From = as.Date(c("2015-01-01","2015-01-01","2015-01-01","2015-01-01","2015-01-01","2015-01-01","2015-01-01","2015-01-01","2015-01-01","2016-01-01","2015-01-01","2015-01-01"))
To = as.Date(c("2016-01-01", NA, "2015-01-01", "2016-01-01", "2017-01-01", "2016-01-01", "2017-01-01", "2016-01-01","2016-01-01","2017-01-01","2016-01-01","2016-01-01"))
df = data.frame(ID, Feature, From, To)


#which looks like this:

   ID Feature       From         To
1   1       A 2015-01-01 2016-01-01
2   1       A 2015-01-01       <NA>
3   2       A 2015-01-01 2015-01-01
4   2       A 2015-01-01 2016-01-01
5   2       A 2015-01-01 2017-01-01
6   3       A 2015-01-01 2016-01-01
7   3       B 2015-01-01 2017-01-01
8   4       B 2015-01-01 2016-01-01
9   5       B 2015-01-01 2016-01-01
10  5       B 2016-01-01 2017-01-01
11  6       B 2015-01-01 2016-01-01
12  6       C 2015-01-01 2016-01-01

我想删除除了最后一个变量之外在每个变量上重复的所有模糊情况(ID 1和2都是这种情况)。数据集中允许任何其他方差或重复。

  

编辑:也许,我应该指定Feature变量意味着a   劳动力市场的某些不利因素(如被禁用,   单身父母,没有工作经验的年轻毕业生等)。所以一个   人可能有多个缺点,这些可能会发生多次   倍。我编辑了原始样本df以允许这种差异。

我的理想样本df将保留这些案例:

   ID Feature       From         To
6   3       A 2015-01-01 2016-01-01
7   3       B 2015-01-01 2017-01-01
8   4       B 2015-01-01 2016-01-01
9   5       B 2015-01-01 2016-01-01
10  5       B 2016-01-01 2017-01-01
11  6       B 2015-01-01 2016-01-01
12  6       C 2015-01-01 2016-01-01

我一直在尝试查看有关重复和不同功能的其他SO问题,但找不到类似的帖子。我认为我的问题与this帖子中描述的问题不同,因为我不关心我的数据集中保留的案例(功能)的数量,只要它们的日期不矛盾。通过condradiction我的意思是一个功能被识别两次,具有相同的开始日期,但不同的结束日期。在这些情况下,我不知道选择哪一个,所以我更愿意完全删除它们。

我一直在玩这些功能,例如:像这样:

select = !duplicated(df[,1:3])
df[select,]

但无法找到如何删除两个重复案例对的方法,而不仅仅是第二个案例。 提前感谢您的任何提示!

2 个答案:

答案 0 :(得分:1)

实现删除重复行的所有实例的一种方法是颠倒duplicated函数的变量顺序,它总是:

  

返回第一个重复条目x [i]

的索引i

使用此功能,我们可以组合正向和反向传递以删除包含重复数据的所有行。

# first pass
s1 = !duplicated(df[,1:3])
# second pass on the data.frame with reversed order in each column
s2 = !duplicated(apply(df[,1:3], 2, rev))
# the second pass needs to be back-reversed to match the original df
df[s1 & rev(s2), ]
   ID Feature       From         To
 5  3       A 2015-01-01 2016-01-01
 6  3       B 2015-01-01 2017-01-01

或者我们可以使用@dalloliogm指出的更优雅的解决方案,并将duplicated应用于参数fromLast = TRUE

s2 = !duplicated(df[,1:3], fromLast = TRUE)
df[s1 & s2, ]

答案 1 :(得分:1)

  

我想删除所有在每个案例上重复的暧昧案例   变量,除了最后一个(ID 1和2),但保留任何其他变量   方差类型,例如,如果ID具有多个要素(ID 3)。

如果你可以做一个更长的例子,那么回答你会容易一些。我不清楚

首先,确定哪些行具有更多“可变性”,例如每个ID有多个功能:

> library(tidyverse)
> df %>% group_by(ID) %>% mutate(n_features=n_distinct(Feature))
# A tibble: 6 x 5
# Groups:   ID [3]
     ID Feature       From         To n_features
  <int>  <fctr>     <date>     <date>      <int>
1     1       A 2015-01-01 2016-01-01          1
2     1       A 2015-01-01         NA          1
3     2       A 2015-01-01 2016-01-01          1
4     2       A 2015-01-01 2017-01-01          1
5     3       A 2015-01-01 2016-01-01          2
6     3       B 2015-01-01 2017-01-01          2

其次,删除所有重复的行,但具有“可变性”的行除外:

> df %>% 
       group_by(ID) %>% 
       mutate(n_features=n_distinct(Feature)) %>% 
       ungroup %>% 
       filter(
               (!duplicated(Feature, From, To) | !duplicated(Feature, From, To, fromLast=T))| n_features>1)
# A tibble: 2 x 5
     ID Feature       From         To n_features
  <int>  <fctr>     <date>     <date>      <int>
1     3       A 2015-01-01 2016-01-01          2
2     3       B 2015-01-01 2017-01-01          2