R 如何平均多个大小不等的数据帧中的元素?
我有一系列的文本文件,100个具有相同结构的文件,以及所有文件中每个元素需要平均的列数。我使用的是以下代码: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:
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)