我在数据框架上使用融合和均值时遇到问题。也许这只是一个初学者问题。
我有一个包含两个条件和3个重复的数据框
set.seed(1)
testdf <- data.frame(name1=letters[1:5],con1_1=floor(runif(5,20,35)),con1_2=floor(runif(5,20,35)),con1_3=floor(runif(5,20,35)),con2_1=floor(runif(5,20,35)),con2_2=floor(runif(5,20,35)),con2_3=floor(runif(5,20,35)))
print(testdf)
name1 con1_1 con1_2 con1_3 con2_1 con2_2 con2_3
1 a 23 33 23 27 34 25
2 b 25 34 22 30 23 20
3 c 28 29 30 34 29 25
4 d 33 29 25 25 21 33
5 e 23 20 31 31 24 25
现在我融化了数据框以得到这样的东西,我想知道每个条件的平均值......
melt(testdf[1:7],id.vars='name1')
name1 variable value mean_con1 mean_con2
1 a con1_1 23 26.33333 28.66667
2 b con1_1 25 27.00000 24.33333
3 c con1_1 28 29.00000 29.33333
4 d con1_1 33 29.00000 26.33333
5 e con1_1 23 24.66667 26.66667
6 a con1_2 33 26.33333 28.66667
7 b con1_2 34 27.00000 24.33333
8 c con1_2 29 29.00000 29.33333
9 d con1_2 29 29.00000 26.33333
10 e con1_2 20 24.66667 26.66667
11 a con1_3 23 26.33333 28.66667
...
有没有办法用融化的数据框计算平均值,还是我必须重新创建原始数据框并计算下面的平均值?
testdf$mean_con1 <- apply(testdf[2:4],1,mean)
testdf$mean_con2 <- apply(testdf[5:7],1,mean)
修改
我刚才意识到,我在问题中犯了一个错误。你的答案是正确的,但我实际上正在寻找的只是一栏中的手段。根据变量交替... 这有意义吗?
melt(testdf[1:7],id.vars='name1')
name1 variable value mean
1 a con1_1 23 26.33333
2 b con1_1 25 27.00000
3 c con1_1 28 29.00000
4 d con1_1 33 29.00000
5 e con1_1 23 24.66667
6 a con1_2 33 26.33333
7 b con1_2 34 27.00000
...
16 a con2_1 27 28.66667
17 b con2_1 30 24.33333
18 c con2_1 34 29.33333
19 d con2_1 25 26.33333
20 e con2_1 31 26.66667
21 a con2_2 34 28.66667
22 b con2_2 23 24.33333
...
好吧,也许我会解释一下我要做的事情。我想用ggplot绘制数据,我想将表示平均值的值和值作为geom_points作为叠加。我希望通过复制来对点进行着色并根据条件对所有内容进行分组...希望有人有个想法......
答案 0 :(得分:3)
这是一种使用&#34; dplyr&#34;和&#34; tidyr&#34;:
library(dplyr)
library(tidyr)
testdf %>%
gather(var, val, con1_1:con2_3) %>%
separate(var, c("var", "time")) %>%
group_by(name1, var) %>%
summarise(mVal = mean(val)) %>%
spread(var, mVal)
# Source: local data frame [5 x 3]
#
# name1 con1 con2
# 1 a 26.33333 28.66667
# 2 b 27.00000 24.33333
# 3 c 29.00000 29.33333
# 4 d 29.00000 26.33333
# 5 e 24.66667 26.66667
如果您希望数据保持长格式,请尝试:
testdf %>%
gather(var, val, con1_1:con2_3) %>%
separate(var, c("var", "time")) %>%
group_by(name1, var) %>%
mutate(mVal = mean(val))
等同于&#34; reshape2&#34;将使用colsplit
分割您的&#34;变量&#34;列,并使用dcast
获取汇总结果。
library(reshape2)
dfL <- melt(testdf, id.vars = "name1")
dfL <- cbind(dfL, colsplit(dfL$variable, "_", c("var", "time")))
dcast(dfL, name1 ~ var, value.var = "value", mean)
# name1 con1 con2
# 1 a 26.33333 28.66667
# 2 b 27.00000 24.33333
# 3 c 29.00000 29.33333
# 4 d 29.00000 26.33333
# 5 e 24.66667 26.66667
同样,但长篇大论是:
library(reshape2)
dfL <- melt(testdf, id.vars = "name1")
dfL <- cbind(dfL, colsplit(dfL$variable, "_", c("var", "time")))
dfL$mVal <- with(dfL, ave(value, name1, var))
答案 1 :(得分:1)
使用base
函数
df1 <- reshape(testdf, idvar="name1", varying=2:7, direction="long",sep="_")
aggregate(df1[,3:4], list(name1=df1[,1]), FUN=mean)
# name1 con1 con2
#1 a 26.33333 28.66667
#2 b 27.00000 24.33333
#3 c 29.00000 29.33333
#4 d 29.00000 26.33333
#5 e 24.66667 26.66667
或者您可以使用data.table
计算重塑后的平均值
library(data.table)
setDT(df1)[, lapply(.SD, mean),.SDcols=c("con1", "con2"), by=name1]
# name1 con1 con2
#1: a 26.33333 28.66667
#2: b 27.00000 24.33333
#3: c 29.00000 29.33333
#4: d 29.00000 26.33333
#5: e 24.66667 26.66667
如果您需要长格式
library(reshape2)
res <- within( melt(testdf, id="name1"), {
variable<- gsub("\\_.*","",variable)
Mean<- ave(value, name1,variable)})
head(res)
# name1 variable value Mean
#1 a con1 23 26.33333
#2 b con1 25 27.00000
#3 c con1 28 29.00000
#4 d con1 33 29.00000
#5 e con1 23 24.66667
#6 a con1 33 26.33333
library(ggplot2)
res$repl <- rep(rep(1:3, each=5),2)
p <- ggplot(res, aes(name1, Mean))
p +
geom_bar(position="dodge", stat="identity", fill="LightBlue") +
geom_point(data=res, aes(name1, value, colour=repl))+
facet_wrap(~variable) +
theme_bw()
答案 2 :(得分:0)
set.seed(1)
testdf <- data.frame(name1=letters[1:5],con1_1=floor(runif(5,20,35)),con1_2=floor(runif(5,20,35)),con1_3=floor(runif(5,20,35)),con2_1=floor(runif(5,20,35)),con2_2=floor(runif(5,20,35)),con2_3=floor(runif(5,20,35)))
require(reshape2)
melted <- melt(testdf[1:7],id.vars='name1')
mean(melted$value)
输出:
> mean(melted$value)
[1] 27.16667
答案 3 :(得分:0)
您可以使用融合框架上ddply
包中的plyr
方法:
require(ddply)
m = melt(testdf[1:7],id.vars='name1')
reshape(ddply(m, .(name1, con=substr(variable, 1,4)), summarize, m = mean(value)), timevar="con", idvar="name1", direction="wide")
这给了
name1 m.con1 m.con2
1 a 26.33333 28.66667
3 b 27.00000 24.33333
5 c 29.00000 29.33333
7 d 29.00000 26.33333
9 e 24.66667 26.66667
答案 4 :(得分:0)
然后你可以使用'aggregate'。
set.seed(1)
testdf <- data.frame(name1=letters[1:5],con1_1=floor(runif(5,20,35)),con1_2=floor(runif(5,20,35)),con1_3=floor(runif(5,20,35)),con2_1=floor(runif(5,20,35)),con2_2=floor(runif(5,20,35)),con2_3=floor(runif(5,20,35)))
require(reshape2)
melted <- melt(testdf[1:7],id.vars='name1')
meanbygroup <- aggregate(melted$value, by=list(melted$variable), FUN=mean)