R 如何平均多个大小不等的数据帧中的元素?

R 如何平均多个大小不等的数据帧中的元素?,r,dataframe,average,reduce,R,Dataframe,Average,Reduce,我有一系列的文本文件,100个具有相同结构的文件,以及所有文件中每个元素需要平均的列数。我使用的是以下代码: my.list<-list() for(j in 1:100){ my.list[[j]]<-read.table(paste('file_',j,'.txt',sep='') ,header=TRUE) } all=Reduce("+", my.list) / length(my.list) 文件2:

我有一系列的文本文件,100个具有相同结构的文件,以及所有文件中每个元素需要平均的列数。我使用的是以下代码:

my.list<-list()
for(j in 1:100){
  my.list[[j]]<-read.table(paste('file_',j,'.txt',sep='')
                               ,header=TRUE)
}

all=Reduce("+", my.list) / length(my.list)
文件2:

           x
1 4
2 2
3 6
4 1
5 9
6 2
我想要一个输出:

          x
1 3.5
2 3.5
3 3.5
4 4.5
5 5.5
6 4
7 0
提前感谢

我们可以使用data.table中的rbindlist来rbind列表元素listx,y。id.col=TRUE为每个列表元素生成id。创建一个按.id分组的序列索引.idx,使用.idx作为分组变量,并使用lappy获得datatable.SD子集的平均值。.SDcols指定要为平均值计算选择的列

library(data.table) # data.table_1.9.5 
rbindlist(list(x,y), idcol=TRUE)[,.idx:=1:.N , by = .id][, 
                  lapply(.SD, mean), .SDcols=2:3, by= .idx]
#    .idx Col1 Col2
#1:    1    1  3.5
#2:    2    2  3.5
#3:    3    3  3.5
#4:    4    4  4.5
#5:    5    5  5.5
#6:    6    6  4.0
#7:    7    7  0.0
或者我们可以使用@David Arenburg建议的另一个选项。除了使用colMeans而不是lappy.SD外,步骤与上面相同

使现代化 假设数据集具有来自多个数据集的变量ncol,我们可以使用fread读取工作目录中的所有文件,使用带有fill=TRUE的rbindlist,并使用上面的代码以及.SDcols中的适当更改

数据 我们可以使用data.table中的rbindlist来rbind列表元素listx,y。id.col=TRUE为每个列表元素生成id。创建一个按.id分组的序列索引.idx,使用.idx作为分组变量,并使用lappy获得datatable.SD子集的平均值。.SDcols指定要为平均值计算选择的列

library(data.table) # data.table_1.9.5 
rbindlist(list(x,y), idcol=TRUE)[,.idx:=1:.N , by = .id][, 
                  lapply(.SD, mean), .SDcols=2:3, by= .idx]
#    .idx Col1 Col2
#1:    1    1  3.5
#2:    2    2  3.5
#3:    3    3  3.5
#4:    4    4  4.5
#5:    5    5  5.5
#6:    6    6  4.0
#7:    7    7  0.0
或者我们可以使用@David Arenburg建议的另一个选项。除了使用colMeans而不是lappy.SD外,步骤与上面相同

使现代化 假设数据集具有来自多个数据集的变量ncol,我们可以使用fread读取工作目录中的所有文件,使用带有fill=TRUE的rbindlist,并使用上面的代码以及.SDcols中的适当更改

数据
以下解决方案使用zoo包

install.packages("zoo")
library(zoo)
两个不等向量

对于2个以上的向量:

不等矩阵


注:在提供的示例中,缺失的元素用NA填充。如果使用cbindz1、z2、fill=0,则NA将被零值填充,从而产生不同的行平均值。

以下解决方案使用zoo软件包

install.packages("zoo")
library(zoo)
两个不等向量

对于2个以上的向量:

不等矩阵



注:在提供的示例中,缺失的元素用NA填充。如果使用cbindz1,z2,fill=0,则NA将被零值填充,这会产生不同的行平均值。

我建议使用as.listcolMeans.SD而不是lappy.SD,按原样平均vectorized@DavidArenburg谢谢,我认为这是一个更好的替代品。出于好奇,我将尝试一些基准测试。谢谢你的回答。但问题是我有超过100个数据帧。在某些情况下,它们有多个列。这就是我为什么使用“减少”的原因。为了简单起见,我只举了一个1列的例子。@mahmood您必须展示一个模仿原始数据集的例子。当您显示两个包含n列的数据集时,我认为应该是原始数据集的情况,唯一的区别在于nrows。话虽如此,您可以使用带有fill=TRUE的rbindlist来填充不相等的列NAs@mahmood另外,如果有上百个数据集,最好使用fread和lappy直接读取它vectorized@DavidArenburg谢谢,我认为这是一个更好的替代品。出于好奇,我将尝试一些基准测试。谢谢你的回答。但问题是我有超过100个数据帧。在某些情况下,它们有多个列。这就是我为什么使用“减少”的原因。为了简单起见,我只举了一个1列的例子。@mahmood您必须展示一个模仿原始数据集的例子。当您显示两个包含n列的数据集时,我认为应该是原始数据集的情况,唯一的区别在于nrows。话虽如此,您可以使用带有fill=TRUE的rbindlist来填充不相等的列NAs@mahmood另外,如果有100个数据集,最好使用fread和lapply直接阅读。你能试试更新后的代码吗?是的,我在努力:我会让你updtaed@mahmood:您是希望在此示例2中按整个数据集中的列总数进行平均,还是按特定行中的数据数进行平均?对于第7行,这是1?这可能会使您的结果有所不同。@RuthgerRighart按特定行中的数据数计算。@mahmood:只针对记录,zoo软件包提供了另一种选择,请参见下面的答案。你能试试更新后的代码吗?是的,我正在尝试:我会留下你的updtaed@mahmood:您是希望在此示例2中按整个数据集中的列总数进行平均,还是按特定行中的数据数进行平均?对于第7行,这是1?这可能会使您的结果有所不同。@RuthgerRighart根据特定行中的数据数量进行排序。@mahmood:仅针对记录,zoo软件包提供了另一种选择o
关于这一点,请参见下面的答案。用NAs填充,然后就意味着…,na.rm=TOf课程。用NAs填充,然后就意味着…,na.rm=T
  lst <- list(x,y,z)
  rbindlist(lst, idcol=TRUE, fill=TRUE)[, 
     .idx:=1:.N, by=.id][, as.list(colMeans(.SD, na.rm=TRUE)),
               .SDcols=2:4, by=.idx][,-1, with=FALSE]
  #    Col1     Col2 Col3
  #1:    1 3.000000    3
  #2:    2 3.333333    4
  #3:    3 3.666667    5
  #4:    4 4.666667    6
  #5:    5 5.666667    7
  #6:    6 4.000000  NaN
  #7:    7 0.000000  NaN
   Dim1 <- sapply(lst, dim)
   d1 <- as.data.frame(matrix(NA, ncol=max(Dim1[2,]), 
                              nrow=max(Dim1[1,])))
   nm1 <- unique(unlist(sapply(lst, colnames)))
   names(d1) <- nm1
   lst1 <-Map(function(x,y) {
      y[match(row.names(x), row.names(y)),
                  match(colnames(x), colnames(y))] <- x
       y }, 
       lst, list(d1))

 ar1 <- array(unlist(lst1), dim=c(max(Dim1[1,]), max(Dim1[2,]), length(lst1)))
 apply(ar1, c(1,2), mean, na.rm=TRUE)
 #      [,1]     [,2] [,3]
 #[1,]    1 3.000000    3
 #[2,]    2 3.333333    4
 #[3,]    3 3.666667    5
 #[4,]    4 4.666667    6
 #[5,]    5 5.666667    7
 #[6,]    6 4.000000  NaN
 #[7,]    7 0.000000  NaN
x <- structure(list(Col1 = 1:7, Col2 = c(3L, 5L, 1L, 8L, 2L, 6L, 0L
)), .Names = c("Col1", "Col2"), class = "data.frame", row.names = 
c(NA, -7L))

y <- structure(list(Col1 = 1:6, Col2 = c(4L, 2L, 6L, 1L, 9L, 2L)), 
.Names = c("Col1", "Col2"), class = "data.frame", row.names = c(NA, 
-6L))

z <- data.frame(Col1=1:5, Col2=2:6, Col3=3:7)
install.packages("zoo")
library(zoo)
file1<-c(3,5,1,8,2,6,0)
file2<-c(4,2,6,1,9,2)

z1<-zoo(file1)
z2<-zoo(file2)

dat<-cbind(z1,z2)

rowMeans(dat, na.rm=TRUE)
file3<-c(2,3)
z3<-zoo(file3)
dat<-cbind(z1,z2,z3)

rowMeans(dat, na.rm=TRUE)
z1<-zoo(cbind(c(1,2,3),c(0,2,7)))
z2<-zoo(cbind(c(0,3,4,7,2),c(1,4,2,3,8)))

dat<-cbind(z1,z2)
rowMeans(dat, na.rm=TRUE)