删除条件为R的重复条目列表

时间:2016-09-06 12:25:42

标签: r

我在R中有一个名为data的列表。数据包含CustIDEndDate列。

我想要做的是搜索比较CustID的列表,找到具有相同CustID的重复条目。

在找到的条目中,我想比较EndDate并从列表中删除值最小的条目(最早的EndDate)。

我不知道如何处理这个问题,因为我不习惯在R中使用这些函数。

2 个答案:

答案 0 :(得分:1)

CustID  <- c(seq(1,10,1),seq(1,5,1))
EndDate <- c(Sys.Date(),rep(seq(Sys.Date(),Sys.Date()+6, 1),2))

# Let's assume you're starting with a list
data <- list(CustID, EndDate)

列表如下所示:

[[1]]
 [1]  1  2  3  4  5  6  7  8  9 10  1  2  3  4  5

[[2]]
 [1] "2016-09-06" "2016-09-06" "2016-09-07" "2016-09-08" "2016-09-09" "2016-09-10" "2016-09-11" "2016-09-12" "2016-09-06"
[10] "2016-09-07" "2016-09-08" "2016-09-09" "2016-09-10" "2016-09-11" "2016-09-12"
# To make matching CustID and EndDate easy let's change it to a DF
df1           <- as.data.frame(data)
colnames(df1) <- c("CustID", "EndDate")

data.frame看起来像这样:

   CustID    EndDate
1       1 2016-09-06
2       2 2016-09-06
3       3 2016-09-07
4       4 2016-09-08
5       5 2016-09-09
6       6 2016-09-10
7       7 2016-09-11
8       8 2016-09-12
9       9 2016-09-06
10     10 2016-09-07
11      1 2016-09-08
12      2 2016-09-09
13      3 2016-09-10
14      4 2016-09-11
15      5 2016-09-12
# Find duplicated CustID
dupID <- duplicated(df1$CustID)
dupdf <- df1[df1$CustID %in% df1$CustID[dupID],]

# Remove the entry with the oldest EndDate for each ID
res <- data.frame(CustID=NA, EndDate = as.Date(NA))

for(i in unique(dupdf$CustID)){
  tmp <- dupdf[dupdf$CustID == i, ]
  res <- rbind(res,tmp[!tmp$EndDate == min(tmp$EndDate),])
}
res <- res[!is.na(res$EndDate),]

结果(res)包含重复的客户ID(custID),每个ID都删除了最早的EndDate

   CustID    EndDate
11      1 2016-09-08
12      2 2016-09-09
13      3 2016-09-10
14      4 2016-09-11
15      5 2016-09-12

如果您需要矢量化解决方案,可以使用data.table

require(data.table)
dupdf <- data.table(dupdf)
dupdf[,.(
  EndDate = max(EndDate)
), by = CustID]

评论的建议是

data <- as.data.frame(data)
subset(data, as.logical(ave(as.numeric(EndDate), CustID, FUN = function(x) { 
  length(x) == 1L | x != min(x)
})))

答案 1 :(得分:0)

以下是使用dplyr软件包的解决方案

data <- list(CustID=c(seq(1,10,1),seq(1,5,1),3,3,3), 
         EndDate=c(Sys.Date(),
                   rep(seq(Sys.Date(),Sys.Date()+6, 1),2),
                   Sys.Date()+6, Sys.Date()+6, Sys.Date()+10
                   ))

#Convert list to data frame and remove oldest duplicates
data %>% 
  do.call(cbind.data.frame,.) %>%
  group_by(CustID) %>% 
  summarise_all(funs(last)) %>% 
  ungroup

ID“3”出现5次,包括将要保留的日期的重复。函数“summarize”根据传递的参数将分组变量(在本例中为ClustID)减少为单个观察。在这种情况下,“最后”功能保持最近的观察在同一天忽略重复。

如果您的数据不是按时间顺序排列,请使用安排(desc(EndDate))来订购数据。