4

在 RI 中有一个 data.frame,其中有几个变量,这些变量在几年内每月测量一次。我想得出每个变量的月平均值(使用所有年份)。理想情况下,这些新变量将全部放在一个新的 data.frame 中(携带 ID),下面我只是将新变量添加到 data.frame 中。我目前知道如何做到这一点的唯一方法(如下)似乎相当费力,我希望在 R 中可能有一种更聪明的方法来做到这一点,这不需要像我在下面所做的那样每个月都输入变量和变量。

# Example data.frame with only two years, two month, and two variables
# In the real data set there are always 12 months per year 
# and there are at least four variables
df<- structure(list(ID = 1:4, ABC.M1Y2001 = c(10, 12.3, 45, 89), ABC.M2Y2001 = c(11.1, 
          34, 67.7, -15.6), ABC.M1Y2002 = c(-11.1, 9, 34, 56.5), ABC.M2Y2002 = c(12L,
          13L, 11L, 21L), DEF.M1Y2001 = c(14L, 14L, 14L, 16L), DEF.M2Y2001 = c(15L,
          15L, 15L, 12L), DEF.M1Y2002 = c(5, 12, 23.5, 34), DEF.M2Y2002 = c(6L,
          34L, 61L, 56L)), .Names = c("ID", "ABC.M1Y2001", "ABC.M2Y2001","ABC.M1Y2002", 
          "ABC.M2Y2002", "DEF.M1Y2001", "DEF.M2Y2001", "DEF.M1Y2002", 
          "DEF.M2Y2002"), class = "data.frame", row.names = c(NA, -4L))


# list variable to average for ABC Month 1 across years
ABC.M1.names <- c("ABC.M1Y2001", "ABC.M1Y2002") 
df <- transform(df,  ABC.M1 = rowMeans(df[,ABC.M1.names], na.rm = TRUE))

# list variable to average for ABC Month 2 across years
ABC.M2.names <- c("ABC.M2Y2001", "ABC.M2Y2002") 
df <- transform(df,  ABC.M2 = rowMeans(df[,ABC.M2.names], na.rm = TRUE))

# and so forth for ABC
# ...

# list variables to average for DEF Month 1 across years
DEF.M1.names <- c("DEF.M1Y2001", "DEF.M1Y2002") 
df <- transform(df,  DEF.M1 = rowMeans(df[,DEF.M1.names], na.rm = TRUE))

# and so forth for DEF
# ...
4

4 回答 4

2

这是使用data.table开发版本v1.8.11的解决方案(具有为 data.table 实现的方法)meltcast

require(data.table)
require(reshape2) # melt/cast builds on S3 generic from reshape2
dt <- data.table(df) # where df is your data.frame
dcast.data.table(melt(dt, id="ID")[, sum(value)/.N, list(ID, 
        gsub("Y.*$", "", variable))], ID ~ gsub)
   ID ABC.M1 ABC.M2 DEF.M1 DEF.M2
1:  1  -0.55  11.55   9.50   10.5
2:  2  10.65  23.50  13.00   24.5
3:  3  39.50  39.35  18.75   38.0
4:  4  72.75   2.70  25.00   34.0

您可以将其仅cbind用于您的原始数据。

请注意,这是 S3 通用sum的原语。mean因此,使用sum(.)/length(.)更好(如果分组太多,mean为每个组分配正确的方法可能是一个相当耗时的操作)。.N是 data.table 中的一个特殊变量,它直接为您提供组的长度。

于 2013-11-08T15:29:26.990 回答
1

当您有大量数据并使用正则表达式来提取变量名称和月份时,这是一个使用reshape2该解决方案更加自动化的解决方案。这个解决方案会给你一个很好的汇总表。

#  Load required package
require(reshape2)

#  Melt your wide data into long format
mdf <- melt(df , id = "ID" )

#  Extract relevant variable names from the variable colum
mdf$Month <- gsub( "^.*\\.(M[0-9]{1,2}).*$" , "\\1" , mdf$variable )
mdf$Var <- gsub( "^(.*)\\..*" , "\\1" , mdf$variable )   

#  Aggregate by month and variable
dcast( mdf , Var ~ Month , mean  )
#  Var      M1     M2
#1 ABC 30.5875 19.275
#2 DEF 16.5625 26.750

或者与其他解决方案兼容,并返回表格ID...

dcast( mdf , ID ~ Var + Month , mean  )
#  ID ABC_M1 ABC_M2 DEF_M1 DEF_M2
#1  1  -0.55  11.55   9.50   10.5
#2  2  10.65  23.50  13.00   24.5
#3  3  39.50  39.35  18.75   38.0
#4  4  72.75   2.70  25.00   34.0
于 2013-11-08T15:27:30.207 回答
1

这在基础 R 中非常简单。

mean.names <- split(names(df)[-1], gsub('Y[0-9]{4}$', '', names(df)[-1]))
means <- lapply(mean.names, function(x) rowMeans(df[, x], na.rm = TRUE))
data.frame(df, means)

这将为您提供原始data.frame文件,最后有以下四列:

  ABC.M1 ABC.M2 DEF.M1 DEF.M2
1  -0.55  11.55   9.50   10.5
2  10.65  23.50  13.00   24.5
3  39.50  39.35  18.75   38.0
4  72.75   2.70  25.00   34.0
于 2013-11-08T15:27:36.987 回答
1

您可以使用Reshapefrom package {splitstackshape} 然后使用 plyr package 或 data.table 或 base R 来执行均值。

   library(splitstackshape) # Reshape
    library(plyr) # ddply
    kk<-Reshape(df,id.vars="ID",var.stubs=c("ABC.M1","ABC.M2","DEF.M1","DEF.M2"),sep="")
> kk
  ID AE DB time ABC.M1 ABC.M2 DEF.M1 DEF.M2
1  1 NA NA    1   10.0   11.1   14.0     15
2  2 NA NA    1   12.3   34.0   14.0     15
3  3 NA NA    1   45.0   67.7   14.0     15
4  4 NA NA    1   89.0  -15.6   16.0     12
5  1 NA NA    2  -11.1   12.0    5.0      6
6  2 NA NA    2    9.0   13.0   12.0     34
7  3 NA NA    2   34.0   11.0   23.5     61
8  4 NA NA    2   56.5   21.0   34.0     56

ddply(kk[,c(1,5:8)],.(ID),colwise(mean))
  ID ABC.M1 ABC.M2 DEF.M1 DEF.M2
1  1  -0.55  11.55   9.50   10.5
2  2  10.65  23.50  13.00   24.5
3  3  39.50  39.35  18.75   38.0
4  4  72.75   2.70  25.00   34.0
于 2013-11-08T15:41:59.863 回答