我在R中有一個名爲data的列表。數據具有列CustID
和EndDate
。刪除帶條件的重複條目列表R
我想要做的就是搜索比較CustID
的列表以找到與CustID
相同的重複條目。
在找到的條目上,我想比較EndDate
,並從列表中刪除最低值(最舊的EndDate
)的條目。
我有,因爲我不是很習慣在R.具有這些功能的工作
我在R中有一個名爲data的列表。數據具有列CustID
和EndDate
。刪除帶條件的重複條目列表R
我想要做的就是搜索比較CustID
的列表以找到與CustID
相同的重複條目。
在找到的條目上,我想比較EndDate
,並從列表中刪除最低值(最舊的EndDate
)的條目。
我有,因爲我不是很習慣在R.具有這些功能的工作
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)
})))
謝謝你,善良的先生! –
@ P.Berg樂於幫助!乾杯 –
在一個循環動態增長的對象(如你用'res'做的)是不是真的值得推薦的做法 –
下面是使用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))來排序數據。
如果你有多列並且不想彙總所有,總結(EndDate = last(EndDate)) –
提取最後日期不同於刪除第一個日期,因爲每個ID可能有多於2個條目。 (你可以做'data%>%data.frame()%>%...') –
你的意思是我應該按時間順序排列它們嗎? 「安排(結束日期)」?然後,數據可能會有多個條目按客戶ID排序,並且初始排序也不相關。 –
請爲您的列表提供一個可再現的小例子,例如使用'dput()' – Jimbou
它是一個'list'還是'data.frame'?請檢查[如何創建一個最小可重現的例子](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)並更新您的問題 –
澄清原因@ docendodiscimus問這是因爲列表沒有列。所以目前還不清楚你的意思是列表元素,還是你的意思是data.frame的列。 –