2016-09-06 103 views
1

我在R中有一個名爲data的列表。數據具有列CustIDEndDate刪除帶條件的重複條目列表R

我想要做的就是搜索比較CustID的列表以找到與CustID相同的重複條目。

在找到的條目上,我想比較EndDate,並從列表中刪除最低值(最舊的EndDate)的條目。

我有,因爲我不是很習慣在R.具有這些功能的工作

+2

請爲您的列表提供一個可再現的小例子,例如使用'dput()' – Jimbou

+4

它是一個'list'還是'data.frame'?請檢查[如何創建一個最小可重現的例子](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)並更新您的問題 –

+0

澄清原因@ docendodiscimus問這是因爲列表沒有列。所以目前還不清楚你的意思是列表元素,還是你的意思是data.frame的列。 –

回答

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)與最古老的EndDate每個ID刪除:

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) 
}))) 
+0

謝謝你,善良的先生! –

+0

@ P.Berg樂於幫助!乾杯 –

+3

在一個循環動態增長的對象(如你用'res'做的)是不是真的值得推薦的做法 –

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次,包括在天重複該會被保留。根據傳遞的參數,「彙總」功能將分組變量(在此情況下爲ClustID)減少爲單個觀察值。在這種情況下,「最後」功能會保留最近的觀察,忽略同一天的重複。

如果您的數據不是按時間順序排列,請使用arrange(desc(EndDate))來排序數據。

+0

如果你有多列並且不想彙總所有,總結(EndDate = last(EndDate)) –

+1

提取最後日期不同於刪除第一個日期,因爲每個ID可能有多於2個條目。 (你可以做'data%>%data.frame()%>%...') –

+0

你的意思是我應該按時間順序排列它們嗎? 「安排(結束日期)」?然後,數據可能會有多個條目按客戶ID排序,並且初始排序也不相關。 –