2015-05-01 193 views
1

這是早期post的一個分支,它構建了一個關於簡化我的功能並消除由lapply產生的合併數據幀的討論。儘管dplyrdata.table等工具消除了合併的需要,但我仍然想知道在這種情況下如何合併。我已經簡化了基於這個answer生成列表的函數。將數據幀合併到列表中

#Reproducible data 
Data <- data.frame("custID" = c(1:10, 1:20), 
    "v1" = rep(c("A", "B"), c(10,20)), 
    "v2" = c(30:21, 20:19, 1:3, 20:6), stringsAsFactors = TRUE) 

#Split-Apply function 
res <- lapply(split(Data, Data$v1), function(df) { 
    cutoff <- quantile(df$v2, c(0.8, 0.9)) 
    top_pct <- ifelse(df$v2 > cutoff[2], 10, ifelse(df$v2 > cutoff[1], 20, NA)) 
    na.omit(data.frame(custID = df$custID, top_pct)) 
    }) 

這給了我下面的結果:

$A 
    custID top_pct 
1  1  10 
2  2  20 

$B 
    custID top_pct 
1  1  10 
2  2  20 
6  6  10 
7  7  20 

我想結果是這樣的:

custID A_top_pct B_top_pct 
1  1  10  10 
2  2  20  20 
3  6  NA  10 
4  7  NA  20 

什麼是那裏的最佳方式是什麼?我應該做一些重塑嗎?如果我這樣做,我必須首先合併數據框嗎?

這是我的解決方案,這可能不是最好的。 (在實際應用中,會有列表中的兩個以上的數據幀。)

#Change the new variable name 
names1 <- names(res) 

for(i in 1:length(res)) { 
    names(res[[i]])[2] <- paste0(names1[i], "_top_pct") 
} 

#Merge the results 
res_m <- res[[1]] 
for(i in 2:length(res)) { 
    res_m <- merge(res_m, res[[i]], by = "custID", all = TRUE) 
} 

回答

3

你可以嘗試用Reducemerge

Reduce(function(...) merge(..., by='custID', all=TRUE), res) 
#  custID top_pct.x top_pct.y 
#1  1  10  10 
#2  2  20  20 
#3  6  NA  10 
#4  7  NA  20 

或者作爲@Colonel Beauvel建議,一個更具可讀性的方法將被從library(functional)

library(functional) 
Reduce(Curry(merge, by='custID', all=T), res) 
+2

也許甚至更可讀用'functional'包帶包裹Curry它:'減少(咖喱(合併,通過= 'CUSTID', all = T),res)' –

相關問題