计算相同数据帧的单元格的统计数据(例如平均值)

发布于 2024-11-29 17:46:47 字数 965 浏览 0 评论 0原文

我有一个相同排序的数据帧的列表。更具体地说,这些是我使用 AmeliaII 包进行多重插补后得到的插补数据帧。现在我想创建一个结构相同的新数据框,但包含跨数据框计算的单元格的平均值。

我目前实现这一目标的方法如下:

## do the Amelia run ------------------------------------------------------------

a.out <- amelia(merged, m=5, ts="Year", cs ="GEO",polytime=1)

## Calculate the output statistics ----------------------------------------------
left.side <- a.out$imputations[[1]][,1:2]
a.out.ncol <- ncol(a.out$imputations[[1]])

a <- a.out$imputations[[1]][,3:a.out.ncol]
b <- a.out$imputations[[2]][,3:a.out.ncol]
c <- a.out$imputations[[3]][,3:a.out.ncol]
d <- a.out$imputations[[4]][,3:a.out.ncol]
e <- a.out$imputations[[5]][,3:a.out.ncol]

# Calculate the Mean of the matrices
mean.right <- apply(abind(a,b,c,d,e,f,g,h,i,j,along=3),c(1,2),mean) 

# recombine factors with values
mean <- cbind(left.side,mean.right) 

我认为有更好的方法可以通过使用 apply、plyr 等来做到这一点,但作为 R 新手,我真的有点迷失在这里。您对如何解决这个问题有什么建议吗?

I am having a list of identically sorted dataframes. More specific these are the imputed dataframes which I get after doing Multiple imputations with the AmeliaII package. Now I want to create a new dataframe that is identical in structure, but contains the mean values of the cells calculated across the dataframes.

The way I achieve this at the moment is the following:

## do the Amelia run ------------------------------------------------------------

a.out <- amelia(merged, m=5, ts="Year", cs ="GEO",polytime=1)

## Calculate the output statistics ----------------------------------------------
left.side <- a.out$imputations[[1]][,1:2]
a.out.ncol <- ncol(a.out$imputations[[1]])

a <- a.out$imputations[[1]][,3:a.out.ncol]
b <- a.out$imputations[[2]][,3:a.out.ncol]
c <- a.out$imputations[[3]][,3:a.out.ncol]
d <- a.out$imputations[[4]][,3:a.out.ncol]
e <- a.out$imputations[[5]][,3:a.out.ncol]

# Calculate the Mean of the matrices
mean.right <- apply(abind(a,b,c,d,e,f,g,h,i,j,along=3),c(1,2),mean) 

# recombine factors with values
mean <- cbind(left.side,mean.right) 

I suppose that there is a much better way of doing this by using apply, plyr or the like, but as a R Newbie I am really a bit lost here. Do you have any suggestions how to go about this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

魔法唧唧 2024-12-06 17:46:47

这是使用 Reduceplyr::llply EDIT 的替代方法

dfr1 <- data.frame(a = c(1,2.5,3), b = c(9.0,9,9), c = letters[1:3])
dfr2 <- data.frame(a = c(5,2,5), b = c(6,5,4), c = letters[1:3])

tst = list(dfr1, dfr2)

require(plyr)
tst2 = llply(tst, function(df) df[,sapply(df, is.numeric)]) # strip out non-numeric cols
ans  = Reduce("+", tst2)/length(tst2)

。您可以大大简化代码并用 5 行 R 代码完成您想要的事情。这是使用 Amelia 包的示例。

library(Amelia)
data(africa)

# carry out imputations
a.out      = amelia(x = africa, cs = "country", ts = "year", logs = "gdp_pc") 

# extract numeric columns from each element of a.out$impuations  
tst2       = llply(a.out$imputations, function(df) df[,sapply(df, is.numeric)]) 

# sum them up and divide by length to get mean
mean.right = Reduce("+", tst2)/length(tst2)

# compute fixed columns and cbind with mean.right
left.side  = a.out$imputations[[1]][1:2]
mean0      = cbind(left.side,mean.right) 

Here's an alternate approach using Reduce and plyr::llply

dfr1 <- data.frame(a = c(1,2.5,3), b = c(9.0,9,9), c = letters[1:3])
dfr2 <- data.frame(a = c(5,2,5), b = c(6,5,4), c = letters[1:3])

tst = list(dfr1, dfr2)

require(plyr)
tst2 = llply(tst, function(df) df[,sapply(df, is.numeric)]) # strip out non-numeric cols
ans  = Reduce("+", tst2)/length(tst2)

EDIT. You can simplify your code considerably and accomplish what you want in 5 lines of R code. Here is an example using the Amelia package.

library(Amelia)
data(africa)

# carry out imputations
a.out      = amelia(x = africa, cs = "country", ts = "year", logs = "gdp_pc") 

# extract numeric columns from each element of a.out$impuations  
tst2       = llply(a.out$imputations, function(df) df[,sapply(df, is.numeric)]) 

# sum them up and divide by length to get mean
mean.right = Reduce("+", tst2)/length(tst2)

# compute fixed columns and cbind with mean.right
left.side  = a.out$imputations[[1]][1:2]
mean0      = cbind(left.side,mean.right) 
可遇━不可求 2024-12-06 17:46:47

如果我正确理解你的问题,那么这应该会让你走得很远:

#set up some data:
dfr1<-data.frame(a=c(1,2.5,3), b=c(9.0,9,9))
dfr2<-data.frame(a=c(5,2,5), b=c(6,5,4))
tst<-list(dfr1, dfr2)
#since all variables are numerical, use a threedimensional array
tst2<-array(do.call(c, lapply(tst, unlist)), dim=c(nrow(tst[[1]]), ncol(tst[[1]]), length(tst)))
#To see where you're at:
tst2
#rowMeans for a threedimensional array and dims=2 does the mean over the last dimension
result<-data.frame(rowMeans(tst2, dims=2))
rownames(result)<-rownames(tst[[1]])
colnames(result)<-colnames(tst[[1]])
#display the full result
result

HTH。

If I understand your question correctly, then this should get you a long way:

#set up some data:
dfr1<-data.frame(a=c(1,2.5,3), b=c(9.0,9,9))
dfr2<-data.frame(a=c(5,2,5), b=c(6,5,4))
tst<-list(dfr1, dfr2)
#since all variables are numerical, use a threedimensional array
tst2<-array(do.call(c, lapply(tst, unlist)), dim=c(nrow(tst[[1]]), ncol(tst[[1]]), length(tst)))
#To see where you're at:
tst2
#rowMeans for a threedimensional array and dims=2 does the mean over the last dimension
result<-data.frame(rowMeans(tst2, dims=2))
rownames(result)<-rownames(tst[[1]])
colnames(result)<-colnames(tst[[1]])
#display the full result
result

HTH.

下雨或天晴 2024-12-06 17:46:47

经过多次尝试,我找到了一种相当快速的方法来计算跨多个数据帧的单元格平均值。

# First create an empty data frame for storing the average imputed values. This
# data frame will have the same dimensions of the original one

imp.df <- df

# Then create an array with the first two dimensions of the original data frame and
# the third dimension given by the number of imputations

a <- array(NA, dim=c(nrow(imp.df), ncol(imp.df), length(a.out$imputations)))

# Then copy each imputation in each "slice" of the array

for (z in 1:length(a.out$imputations)) {
a[,,z] <- as.matrix(a.out$imputations[[z]])
}

# Finally, for each cell, replace the actual value with the mean across all 
# "slices" in the array

for (i in 1:dim(a)[1]) {
  for (j in 1:dim(a)[2]) {
imp.df[i, j] <- mean(as.numeric(a[i, j,]))
    }}

After many attempts, I've found a reasonably fast way to calculate cells' means across multiple data frames.

# First create an empty data frame for storing the average imputed values. This
# data frame will have the same dimensions of the original one

imp.df <- df

# Then create an array with the first two dimensions of the original data frame and
# the third dimension given by the number of imputations

a <- array(NA, dim=c(nrow(imp.df), ncol(imp.df), length(a.out$imputations)))

# Then copy each imputation in each "slice" of the array

for (z in 1:length(a.out$imputations)) {
a[,,z] <- as.matrix(a.out$imputations[[z]])
}

# Finally, for each cell, replace the actual value with the mean across all 
# "slices" in the array

for (i in 1:dim(a)[1]) {
  for (j in 1:dim(a)[2]) {
imp.df[i, j] <- mean(as.numeric(a[i, j,]))
    }}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文