我从3个大数据表(名为A1,A2,A3)开始。每个表有4个数据列(V1-V4),1个“日期”列,在所有三个表中都是常量,以及数千行。
这是一些近似我的表的虚拟数据。
A1.V1<-c(1,2,3,4)
A1.V2<-c(2,4,6,8)
A1.V3<-c(1,3,5,7)
A1.V4<-c(1,2,3,4)
A2.V1<-c(1,2,3,4)
A2.V2<-c(2,4,6,8)
A2.V3<-c(1,3,5,7)
A2.V4<-c(1,2,3,4)
A3.V1<-c(1,2,3,4)
A3.V2<-c(2,4,6,8)
A3.V3<-c(1,3,5,7)
A3.V4<-c(1,2,3,4)
Date<-c(2001,2002,2003,2004)
DF<-data.frame(Date, A1.V1,A1.V2,A1.V3,A1.V4,A2.V1,A2.V2,A2.V3,A2.V4,A3.V1,A3.V2,A3.V3,A3.V4)
所以这就是我的数据框最终看起来像:
Date A1.V1 A1.V2 A1.V3 A1.V4 A2.V1 A2.V2 A2.V3 A2.V4 A3.V1 A3.V2 A3.V3 A3.V4
1 2001 1 2 1 1 1 2 1 1 1 2 1 1
2 2002 2 4 3 2 2 4 3 2 2 4 3 2
3 2003 3 6 5 3 3 6 5 3 3 6 5 3
4 2004 4 8 7 4 4 8 7 4 4 8 7 4
我的目标是计算每个数据表中每个匹配列的行平均值。所以在这个例子中,我希望所有列的行均值以V1结尾,所有列以V2结尾,所有列以V3结尾,所有列以V4结尾。
最终结果如下所示
V1 V2 V3 V4
2001 1 2 1 1
2002 2 4 3 2
2003 3 6 5 3
2004 4 8 7 4
所以我的问题是,如何根据列名中的部分匹配来计算行均值?
由于
答案 0 :(得分:7)
colnames = c("V1", "V2", "V3", "V4")
sapply(colnames, function(x) rowMeans(DF [, grep(x, names(DF))] ) )
rownames(res) <- DF$Date
res
V1 V2 V3 V4
2001 1 2 1 1
2002 2 4 3 2
2003 3 6 5 3
2004 4 8 7 4
如果您需要自动生成名称:
> unique(sapply(strsplit(names(DF)[-1], ".", fixed=TRUE), "[", 2) )
[1] "V1" "V2" "V3" "V4"
答案 1 :(得分:4)
library(plyr)
ddply(DF, .(Date), function(x) {
foo <- melt(x, id.vars = 1)
foo$variable <- substr(foo$variable, 4, 6)
return(dcast(foo, Date ~ variable, mean))
})
Date V1 V2 V3 V4
1 2001 1 2 1 1
2 2002 2 4 3 2
3 2003 3 6 5 3
4 2004 4 8 7 4
答案 2 :(得分:2)
您可以grep
与value = T
一起使用以获取相应的名称,然后在eval
的{{1}}组件中创建对j
的调用
data.table
答案 3 :(得分:0)
我确信它可以更优雅地完成,但这是一种似乎有用的可能性。
# declare the column names
colnames = c("V1", "V2", "V3", "V4")
# calculate the means
means = lapply(colnames, function(name) { apply(DF[,grep(name, names(DF))], 1, mean) })
# build the result
result = do.call(cbind, means)
result = as.data.frame(t(result))
rownames(result) = DF$Date
我还应该描述一下,我做了什么。
首先,我宣布列名称部分匹配。
然后,使用grep
命令部分选择数据框中的列(与特定子字符串匹配)。 apply
命令计算均值,lapply
为子字符串部分匹配的所有列执行此操作。
使用do.call
和cbind
(按照DWin的建议),我们将各个列连接起来。
最后,我们从原始数据框的Date
列设置列名称。
问题可以更加有效和高效地解决,请参阅DWin和Maiasaura的解决方案。