根据(部分)匹配列名计算行均值

时间:2012-09-12 22:57:40

标签: r

我从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

所以我的问题是,如何根据列名中的部分匹配来计算行均值?

由于

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)

您可以grepvalue = 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.callcbind(按照DWin的建议),我们将各个列连接起来。 最后,我们从原始数据框的Date列设置列名称。

问题可以更加有效和高效地解决,请参阅DWin和Maiasaura的解决方案。