r - R - 合并分布在数据帧列表中的标识符值
问题描述
我有一个数据框列表
df1 <- data.frame(Symbol = c("A", "A", "B", "C", "D", "D", "D", "E", "E", "A"),
Sample1 = sample(50, 10),
Sample2 = sample(50, 10),
Sample3 = sample(50, 10))
df2 <- data.frame(Symbol = c("B", "B", "B", "E", "A"),
Sample4 = sample(50, 5),
Sample5 = sample(50, 5),
Sample6 = sample(50, 5))
df3 <- data.frame(Symbol = c("A", "B", "C", "D", "E", "F"),
Sample7 = sample(50, 6),
Sample8 = sample(50, 6),
Sample9 = sample(50, 6))
如您所见,每个数据框都有一个名为 的列Symbol
,其中包含出现在列表中多个数据框的值。我希望能够合并它们,这样我就可以选择一些基本的统计数据(例如平均值、第 25 个百分位数等)。最初,我只是这样做
dfList <- list(df1, df2, df3)
df <- reduce(dfList, merge, "Symbol", all = T)
以为我只是取每一行的平均值。但是,我不知道符号在每个数据框中多次出现。所以上面的行实际上合并A
了第一个数据帧中每个出现的say,A
以及第二个和第三个数据帧中的每个出现。这不是我想要的。
Symbol
混乱的解决方案是从整个列表中获取唯一标识符,然后lapply
在它们上面写一个,我在其中搜索每个数据帧中的每个标识符,并提取值。然后我会有一个向量列表,名称是符号标识符。像这样的东西
syms <- unique(as.character(unlist(lapply(dfList, function(x) return(x$Symbol)))))
lst <- lapply(syms, function(x) {
return(unlist(lapply(dfList, function(y) {
return(unlist(y[grep(x, y$Symbol),-1]))
})))
})
names(lst) <- syms
然后我可以取平均值,中位数等......
这在我的实际数据帧上非常慢,我只是认为必须有一种更简单的方法来做到这一点。
编辑:所以最后,我想要这样的东西:
Mean = t(as.data.frame(lapply(lst, function(x) {
return(mean(x))
})))
Min = t(as.data.frame(lapply(lst, function(x) {
return(min(x))
})))
Quantiles = t(as.data.frame(lapply(lst, function(x) {
return(quantile(x, c(0.25, 0.5, 0.75)))
})))
Max = t(as.data.frame(lapply(lst, function(x) {
return(max(x))
})))
df <- cbind(Mean, Min, Quantiles, Max)
colnames(df) <- c("Mean", "Min", "p25", "p50", "p75", "Max")
这将产生
> df
Mean Min p25 p50 p75 Max
A 27.53333 13 21.50 27.0 32.50 48
B 24.33333 2 11.00 21.0 37.50 48
C 26.50000 3 24.00 26.5 32.75 45
D 25.00000 2 12.25 23.5 38.75 49
E 23.25000 2 12.75 22.0 33.75 45
F 21.00000 11 11.50 12.0 26.00 40
解决方案
考虑通过Symbol进行链合并,然后是从宽格式到长格式以及跨多个函数:reshape
aggregate
# MERGE ALL BY Symbol
dfList <- list(df1, df2, df3)
mdf <- Reduce(function(...) merge(..., by="Symbol", all=TRUE), dfList)
# RESHAPE WIDE TO LONG
rdf <- reshape(mdf, varying=names(mdf)[-1], times=names(mdf)[-1],
v.name = "Value", timevar="Sample",
new.row.names = 1:1E4, direction = "long")
# AGGREGATE DATA
agg_raw <- aggregate(Value ~ Symbol, rdf,
function(x) c(Mean=mean(x), Min=min(x), p25=unname(quantile(x)[2]),
p50=median(x), p75=unname(quantile(x)[4]), Max=max(x)))
agg_df <- do.call(data.frame, agg_raw)
colnames(agg_df) <- gsub("Value.", "", colnames(agg_df))
agg_df
# Symbol Mean Min p25 p50 p75 Max
# 1 A 30.77778 3 26.00 33.0 38.00 47
# 2 B 25.29630 3 16.00 23.0 30.50 47
# 3 C 23.00000 4 14.25 24.0 33.75 38
# 4 D 30.77778 2 17.75 34.0 43.00 49
# 5 E 25.38889 3 15.00 22.5 39.75 50
# 6 F 15.66667 13 13.00 13.0 17.00 21
推荐阅读
- python - 使用 awk 系统将特殊字符输入 python sys.argv
- visual-studio-2015 - 使用 Microsoft Azure 逻辑应用企业集成工具的 MSBuild 错误
- cordova - 错误 404 离子部署 Impl http://localhost/plugins/cordova-plugin-ionic/dist/common.js
- logstash - Logtsash Ubuntu 部署问题
- php - 如何在php中循环当前月份的第一天和最后一天?
- java - Java Android 数组键值
- docker - 如何使用 CircleCI 测试我的 docker-compose 设置是否有效?
- batch-processing - 有没有办法从一个驱动器复制选定文件的列表,并将它们分类到另一个驱动器上的相同文件结构中?
- jquery - 使用jquery单击锚标记后如何在同一页面上弹出表单
- genexus - 使用 GX16 U7 SD IOS Generator 调用方法 GeneXus.SD.Media.Camera.TakePhoto() 时应用程序暂停