我有这样的数据集
data
name v1 v2 v3 v4 v5
a 1 2 7 9 3
b 3 8 6 4 8
c 2 5 0 1 9
a 6 0 6 2 1
c 3 9 4 7 5
name
是一个因子变量。我想通过因子v2,v3,v4,v5
计算data$name
的平均值。我使用了以下命令,但它没有用。
tapply(data[,3:6],data$name,mean)
现在,我使用了以下代码
newdata<-0
for (name in unique(data$name)){
rowIndex <- which(data$name == name)
result <- colMeans(data[rowIndex,])
newdata[name,]<-result
}
获得所需的结果。但我想知道是否有一些方法可以做到这一点。
答案 0 :(得分:6)
这是另一种方式
library(data.table)
cols <- paste0("v", 2:5) # set the columns you want to operate on
setDT(data)[, Sums := rowSums(.SD), .SDcols = cols]
data[, list(Means = sum(Sums)/(.N*length(cols))), by = name]
## name Means
## 1: a 3.75
## 2: b 6.50
## 3: c 5.00
修改强>
根据@Aruns的建议,这可能会好得多
setDT(data)[, mean(c(v2,v3,v4,v5)), by=name]
## name V1
## 1: a 3.75
## 2: b 6.50
## 3: c 5.00
或者根据@Anandas建议
library(reshape2)
melt(setDT(data), id.vars = "name", measure.vars = cols)[, mean(value), by = name]
## name V1
## 1: a 3.75
## 2: b 6.50
## 3: c 5.00
答案 1 :(得分:4)
根据预期结果显示:
即。 The expected result for factor a is a (2+7+9+3)+(0+6+2+1)/8
sapply(split(dat[,-(1:2)], dat$name), function(x) sum(x)/prod(dim(x)))
# a b c
# 3.75 6.50 5.00
或者
tapply(rowMeans(dat[,-(1:2)]), dat[,1], sum)/table(dat[,1])
#a b c
#3.75 6.50 5.00
或者
m1 <- as.matrix(dat[,-c(1:2)])
c(by(c(m1), dat[,1][row(m1)], FUN=mean))
# a b c
#3.75 6.50 5.00
或@Ananda Mahto建议的方法
tapply(unlist(dat[-c(1, 2)]), rep(dat$name, 4), mean)
# a b c
#3.75 6.50 5.00
tapply(stack(dat, select = paste0("v", 2:5))$values, rep(dat$name, 4), mean)
# a b c
#3.75 6.50 5.00
答案 2 :(得分:4)
这可以通过dplyr和tidyr包的组合来完成:
library(dplyr)
library(tidyr)
data %>% gather(name, value, v2:v5) %>%
group_by(name) %>% summarize(average=mean(value))
# name average
# 1 a 3.75
# 2 b 6.50
# 3 c 5.00
这是有效的,因为gather
将v2:v5
列合并到一个列中,可以直观地将它们分组:
data %>% gather(name, value, v2:v5)
# name v1 name value
# 1 a 1 v2 2
# 2 b 3 v2 8
# 3 c 2 v2 5
# 4 a 6 v2 0
# 5 c 3 v2 9
# 6 a 1 v3 7
# ...
答案 3 :(得分:2)
编辑:原始答案没有给出正确的结果。这似乎工作正常(选择( - 变量)避免有额外的列,但不需要)
使用dplyr和reshape2包:
library(reshape2)
library(dplyr)
data %>%
select(-v1) %>%
melt %>%
group_by(name) %>%
select(-variable) %>%
summarise_each(funs(mean))
# Source: local data frame [3 x 2]
#
# name value
# 1 a 3.75
# 2 b 6.50
# 3 c 5.00
答案 4 :(得分:0)
所有好的答案,但我只想添加一个:
data <- data.frame(name=as.factor(c("a","b","c","a","c")),
v1=c(1,3,2,6,3),
v2=c(2,8,5,0,9),
v3=c(7,6,0,6,4),
v4=c(9,4,1,2,7),
v5=c(3,8,9,1,5))
u.id <- unique(data$name)
newdata <- t(sapply(unique(u.id),function(c.id){
colMeans(data[data$name == c.id,-1])
}))
rownames(newdata) <- u.id
newdata
v1 v2 v3 v4 v5
a 3.5 1 6.5 5.5 2
b 3.0 8 6.0 4.0 8
c 2.5 7 2.0 4.0 7