1

我在数据框上使用融化和均值时遇到问题。也许这只是一个初学者的问题。

我有一个包含两个条件和 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 作为覆盖。我想通过复制给点上色,并按条件对所有内容进行分组......希望有人有想法......

4

5 回答 5

3

这是使用“dplyr”和“tidyr”的方法:

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))

“reshape2”的等价物将colsplit用于拆分“变量”列,并用于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))
于 2014-08-13T08:52:44.323 回答
2

使用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()

在此处输入图像描述

于 2014-08-13T08:58:52.580 回答
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')
meanbygroup <- aggregate(melted$value, by=list(melted$variable), FUN=mean)
于 2014-08-13T09:07:30.760 回答
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
于 2014-08-13T08:52:23.090 回答
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
于 2014-08-13T08:49:11.247 回答