2015-05-01 153 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)' –

相关问题