我正在尝试学习简化代码并将多个data.frames
(> 2)同时合并到一个数据集中。首先,我想为四个PCA列中的每一列计算“网站”mean
,sd
和n
(每个网站的“个人数”){{1 },Morph_PC1
,...)。其次,将结果合并为单个data.frame。下面是我尝试此任务的示例数据和代码。
我意识到可能有一种方法可以生成一个不需要合并的单个数据集,这很好,但我也想知道如何从包{{1}创建Morph_PC2
命令工作。
示例数据:
merge_all
代码:
reshape
编辑:
现在我有一个很好的结果,可以快速将摘要统计信息分成三个文件,但我仍然遇到问题WW_Data <- structure(list(Individual_ID = c("WW_00A_05", "WW_00A_03", "WW_00A_02",
"WW_00A_01", "WW_00A_04", "WW_00A_06", "WW_00A_08", "WW_00A_09",
"WW_00A_07", "WW_00A_10", "WW_09AB_14", "WW_09AB_09", "WW_09AB_13",
"WW_10AD_01", "WW_10AD_09", "WW_10AD_04", "WW_10AD_02", "WW_10AD_03",
"WW_10AD_07", "WW_10AD_08"), Site_Name = c("Alnön", "Alnön",
"Alnön", "Alnön", "Alnön", "Alnön", "Alnön", "Alnön", "Alnön",
"Alnön", "Anjan", "Anjan", "Anjan", "Anjan", "Anjan", "Anjan",
"Anjan", "Anjan", "Anjan", "Anjan"), Morph_PC1 = c(-2.08424433316496,
-1.85413711191957, -1.67227075271696, -1.0486265729884, -0.809415702756541,
-2.81781338129716, -2.08471369525797, -0.183840575363918, -0.753930407169699,
0.0719252507535882, 1.02353521593315, 1.34441686821234, 0.755249445355964,
-0.564426004755035, 0.720689649641627, -0.243471506156601, -0.245437522679261,
-0.69936850894502, 0.9160796809062, 2.2881261039382), Morph_PC2 = c(1.28499189140338,
-0.349487815669147, 0.0148183164519594, -1.55929148726881, -0.681590397005219,
1.21595114750227, 0.116028310510466, 0.187613229042593, -0.923592436104444,
-1.50956083294446, 1.44864057855388, 1.46254159976068, 1.20375736157205,
0.174071006609975, -0.722049893415186, 1.03516327411773, 0.808851776990861,
-0.928263134752596, -0.175511637463994, -0.389421342417043),
Morph_PC3 = c(-0.445087364125436, -0.704903876393893, 0.161983939922481,
1.14604411022773, 0.701508422965674, -0.78133408496171, -0.306619974141955,
1.05643337302175, 0.163868647932456, -0.673344807228353,
-0.337986608605208, -1.01911125040091, 0.258004835638601,
-0.648040419259003, -0.196770002944659, 0.614010430132367,
0.755886614924319, -0.0631407344114064, -1.28178468134549,
0.226362214551239), Morph_PC4 = c(0.0476276463048772, 0.342957387676778,
-0.117383887482525, 0.289881853573214, 0.649579005842321,
0.600433718752986, 0.295294947111845, -0.293754065807853,
-0.43805381119461, 0.520363554131325, -0.393329204345947,
-1.05629143416274, -0.370922397397109, 0.115121369773473,
0.91445926597504, 0.280048079793911, -0.802245210297552,
0.00368405602889952, -0.251898295768711, -0.607995193037228
)), .Names = c("Individual_ID", "Site_Name", "Morph_PC1",
"Morph_PC2", "Morph_PC3", "Morph_PC4"), row.names = c(36L, 37L,
38L, 39L, 40L, 41L, 42L, 43L, 44L, 45L, 137L, 138L, 139L, 140L,
141L, 142L, 143L, 144L, 145L, 146L), class = "data.frame")
(虽然我不确定我是否应该使用## Calculate statistics for each site ##
WW_PC1_Mean <- subset(melt(tapply(WW_Data$Morph_PC1,list(WW_Data$Site_Name),mean)), value != FALSE)
WW_PC1_SD <- subset(melt(tapply(WW_Data$Morph_PC1,list(WW_Data$Site_Name),sd)), value != FALSE)
WW_PC2_Mean <- subset(melt(tapply(WW_Data$Morph_PC2,list(WW_Data$Site_Name),mean)), value != FALSE)
WW_Site_SD <- subset(melt(tapply(WW_Data$Morph_PC2,list(WW_Data$Site_Name),sd)), value != FALSE)
## merge the all the datasets with one command - THIS FAILS!
WW_Stats <- merge_all(WW_Site_PC1_Mean, WW_Site_PC1_SD, WW_Site_PC2_Mean, by = c("indices"))
- 无论我得到相同的错误)结果。这是我的尝试:
merge_all
错误输出:
merge_recurse
答案 0 :(得分:9)
住在基地R,您可以使用aggregate
:
WW_Data_mean = aggregate(list(mean = WW_Data[, -c(1, 2)]),
list(Site_Name = WW_Data$Site_Name), mean)
WW_Data_sd = aggregate(list(mean = WW_Data[, -c(1, 2)]),
list(Site_Name = WW_Data$Site_Name), sd)
你的代码有几个错误,也许你需要更多地“合并”。
首先是错误。示例中失败的行失败,原因是:
data.frame
应位于list
。WW_Site_Name_PC1_Mean
的对象,但该对象的名称为WW_PC1_Mean
。其次,这里有一些其他的尝试。修复列名:
# Fix your column names
# There's probably an easier way to do this, but...
names(WW_PC1_Mean)[2] = "WW_PC1_Mean"
names(WW_PC1_SD)[2] = "WW_PC1_SD"
names(WW_PC2_Mean)[2] = "WW_PC2_Mean"
names(WW_Site_SD)[2] = "WW_Site_SD"
现在,试试merge_all
。请注意,您需要提供list
data.frame
个。 似乎 merge_all
总是只给出两列---但也许我做错了。
# Not what you want
merge_all(list(WW_PC1_Mean, WW_PC1_SD,
WW_PC2_Mean, WW_Site_SD), by="indices")
indices WW_PC1_Mean
1 Alnön -1.3237067
2 Anjan 0.5295393
转到merge_recurse
。这有效:
# This is what you want
merge_recurse(list(WW_PC1_Mean, WW_PC1_SD,
WW_PC2_Mean, WW_Site_SD), by="indices")
indices WW_PC1_Mean WW_PC1_SD WW_PC2_Mean WW_Site_SD
1 Alnön -1.3237067 0.9252417 -0.220412 0.9912227
2 Anjan 0.5295393 0.9511800 0.391778 0.9112450
您也可以在基础R中使用Reduce
。
# Base R also has a solution
Reduce(function(x, y) merge(x, y, all=TRUE),
list(WW_PC1_Mean, WW_PC1_SD, WW_PC2_Mean, WW_Site_SD))
答案 1 :(得分:7)
我建议你专注于学习一些plyr
善良。
使用[{1}}功能,您可以真正简化代码。以下是使用一行代码计算数据中所有列的ddply
的方法:
mean
同样,标准差:
library(plyr)
ddply(WW_Data, .(Site_Name), numcolwise(mean))
Site_Name Morph_PC1 Morph_PC2 Morph_PC3 Morph_PC4
1 Alnön -1.3237067 -0.220412 0.03185484 0.1896946
2 Anjan 0.5295393 0.391778 -0.16925696 -0.2169369
我经常使用这种类型的分析。有了这个策略,我几乎不必同时合并多个数据帧。
PS。包ddply(WW_Data, .(Site_Name), numcolwise(sd))
Site_Name Morph_PC1 Morph_PC2 Morph_PC3 Morph_PC4
1 Alnön 0.9252417 0.9912227 0.7316201 0.3766064
2 Anjan 0.9511800 0.9112450 0.6698389 0.5717482
已过时了 - 您应该使用reshape
代替,reshape2
功能不再包含merge_all()
答案 2 :(得分:0)
使用具有信息性变量名称的plyr的一些解决方案。
ms <- function(x) cbind("mean"=mean(x),"sd"=sd(x))
do.call(rbind,dlply(WW_Data, .(Site_Name), function(dat) numcolwise(ms)(dat)))
Morph_PC1.mean Morph_PC1.sd Morph_PC2.mean Morph_PC2.sd Morph_PC3.mean Morph_PC3.sd Morph_PC4.mean Morph_PC4.sd
Alnön -1.3237067 0.9252417 -0.2204120 0.9912227 0.03185484 0.73162007 0.1896946 0.3766064
Anjan 0.5295393 0.9511800 0.3917780 0.9112450 -0.16925696 0.66983885 -0.2169369 0.5717482