平均每n列并在r中的新data.frame中保留前两列

时间:2017-08-05 16:03:03

标签: r

我有一个每日时间序列的数据框,每个x和y每天(每6小时)观察4次(我有202552个细胞)。

> head(tab,10)
       x  y X1990.05.01.01.00.00 X1990.05.01.07.00.00 X1990.05.01.13.00.00 X1990.05.01.19.00.00 X1990.05.02.01.00.00 X1990.05.02.07.00.00 X1990.05.02.13.00.00
1  5.000 60             276.9105             277.8516             278.9908             279.2422             279.6751             279.8078             280.4396
2  5.125 60             276.8863             277.8682             278.9966             279.2543             279.6863             279.7885             280.4033
3  5.250 60             276.8621             277.8830             279.0006             279.2659             279.6989             279.7688             280.3661
4  5.375 60             276.8379             277.8969             279.0029             279.2772             279.7123             279.7477             280.3289
5  5.500 60             276.8142             277.9094             279.0033             279.2879             279.7257             279.7244             280.2909
6  5.625 60             276.7913             277.9224             279.0033             279.2987             279.7396             279.6993             280.2523
7  5.750 60             276.7707             277.9363             279.0020             279.3094             279.7531             279.6715             280.2142
8  5.875 60             276.7537             277.9520             279.0002             279.3202             279.7656             279.6406             280.1770
9  6.000 60             276.7416             277.9713             278.9980             279.3314             279.7773             279.6070             280.1407
10 6.125 60             276.7357             277.9946             278.9953             279.3435             279.7871             279.5707             280.1071
   X1990.05.02.19.00.00 X1990.05.03.01.00.00 X1990.05.03.07.00.00 X1990.05.03.13.00.00 X1990.05.03.19.00.00 X1990.05.04.01.00.00 X1990.05.04.07.00.00
1              280.5674             280.3316             280.3796             280.2308             280.6216             280.6216             280.1842
2              280.5414             280.3106             280.3697             280.2133             280.6220             280.6368             280.2053
3              280.5145             280.2886             280.3594             280.1927             280.6184             280.6503             280.2227
4              280.4858             280.2653             280.3482             280.1703             280.6113             280.6619             280.2380
5              280.4562             280.2420             280.3379             280.1466             280.6010             280.6722             280.2492
6              280.4262             280.2192             280.3280             280.1219             280.5880             280.6816             280.2572
7              280.3957             280.1981             280.3209             280.0973             280.5732             280.6910             280.2613
8              280.3661             280.1793             280.3159             280.0748             280.5571             280.7009             280.2626
9              280.3384             280.1640             280.3155             280.0542             280.5414             280.7112             280.2599
10             280.3128             280.1542             280.3195             280.0385             280.5270 

我想计算每4列的每日平均值(因为每天有4次测量)。我能够使用这个功能,但我需要为每一行保留x和y。

### daily mean
byapply <- function(x, by, fun, ...)
{
  # Create index list
  if (length(by) == 1)
  {
    nc <- ncol(x)
    split.index <- rep(1:ceiling(nc / by), each = by, length.out = nc)
  } else # 'by' is a vector of groups
  {
    nc <- length(by)
    split.index <- by
  }
  index.list <- split(seq(from = 1, to = nc), split.index)

  # Pass index list to fun using sapply() and return object
  sapply(index.list, function(i)
  {
    do.call(fun, list(x[, i], ...))
  })
}


DM<- data.frame(byapply(tab[3:2800], 4, rowMeans))
> head(DM, 10)
         X1       X2       X3       X4       X5
1  278.2488 280.1225 280.3909 279.4138 276.6809
2  278.2514 280.1049 280.3789 279.4395 276.7141
3  278.2529 280.0871 280.3648 279.4634 276.7437
4  278.2537 280.0687 280.3488 279.4858 276.7691
5  278.2537 280.0493 280.3319 279.5066 276.7909
6  278.2539 280.0294 280.3143 279.5264 276.8090
7  278.2546 280.0086 280.2974 279.5453 276.8244
8  278.2565 279.9873 280.2818 279.5639 276.8377
9  278.2605 279.9658 280.2688 279.5819 276.8495
10 278.2673 279.9444 280.2598 279.5998 276.8611

然后我可以使用cbind将每日手段与每个x和y链接

lonlat<-tab[-(3:2800)]
DMxy<- data.frame(cbind(lonlat, DM))

但是我正在寻找一种方法,我可以直接计算每日平均值,方法是在新数据框中保留前两列(x和y)(不删除x和y),以尽量减少{{1}中的任何可能错误}}

2 个答案:

答案 0 :(得分:0)

而不是

DM<- data.frame(byapply(tab[3:2800], 4, rowMeans))

DM2 <- cbind(byapply(tab[-(1:2)], 4, rowMeans), tab[1:2])

只需一步即可获得所需的结果。此外,您可以最大限度地减少出错的可能性,因为您不需要知道数据帧的长度; tab[-(1:2)]表示&#34; tab中的每一列除了前两个&#34;。

答案 1 :(得分:0)

经典教科书案例由于需要的操作(例如分组聚合,特别是平均)而不能以宽格式存储数据。考虑将数据融合为长格式,并按每天 X Y 分组进行汇总:

数据 (OP发布的示例但填写了缺失的第10行最后两个值)

txt= '       x  y X1990.05.01.01.00.00 X1990.05.01.07.00.00 X1990.05.01.13.00.00 X1990.05.01.19.00.00 X1990.05.02.01.00.00 X1990.05.02.07.00.00 X1990.05.02.13.00.00 X1990.05.02.19.00.00 X1990.05.03.01.00.00 X1990.05.03.07.00.00 X1990.05.03.13.00.00 X1990.05.03.19.00.00 X1990.05.04.01.00.00 X1990.05.04.07.00.00
1  5.000 60             276.9105             277.8516             278.9908             279.2422             279.6751             279.8078             280.4396              280.5674             280.3316             280.3796             280.2308             280.6216             280.6216             280.1842
2  5.125 60             276.8863             277.8682             278.9966             279.2543             279.6863             279.7885             280.4033              280.5414             280.3106             280.3697             280.2133             280.6220             280.6368             280.2053
3  5.250 60             276.8621             277.8830             279.0006             279.2659             279.6989             279.7688             280.3661              280.5145             280.2886             280.3594             280.1927             280.6184             280.6503             280.2227
4  5.375 60             276.8379             277.8969             279.0029             279.2772             279.7123             279.7477             280.3289              280.4858             280.2653             280.3482             280.1703             280.6113             280.6619             280.2380
5  5.500 60             276.8142             277.9094             279.0033             279.2879             279.7257             279.7244             280.2909              280.4562             280.2420             280.3379             280.1466             280.6010             280.6722             280.2492
6  5.625 60             276.7913             277.9224             279.0033             279.2987             279.7396             279.6993             280.2523              280.4262             280.2192             280.3280             280.1219             280.5880             280.6816             280.2572
7  5.750 60             276.7707             277.9363             279.0020             279.3094             279.7531             279.6715             280.2142              280.3957             280.1981             280.3209             280.0973             280.5732             280.6910             280.2613
8  5.875 60             276.7537             277.9520             279.0002             279.3202             279.7656             279.6406             280.1770              280.3661             280.1793             280.3159             280.0748             280.5571             280.7009             280.2626
9  6.000 60             276.7416             277.9713             278.9980             279.3314             279.7773             279.6070             280.1407              280.3384             280.1640             280.3155             280.0542             280.5414             280.7112             280.2599
10 6.125 60             276.7357             277.9946             278.9953             279.3435             279.7871             279.5707             280.1071              280.3128             280.1542             280.3195             280.0385             280.5270             280.6581             280.3139'

df <- read.table(text=txt, header=TRUE)

<强> CODE

library(reshape2)

mdf <- melt(df, id.vars = c('x', 'y'), variable.name = "day")

mdf$day <- gsub("X", "", mdf$day)
mdf$datetime <- as.POSIXct(mdf$day, format="%Y.%m.%d.%H.%M.%S")
mdf$day <- format(mdf$datetime, "%Y-%m-%d")
head(mdf)
#       x  y        day    value            datetime
# 1 5.000 60 1990-05-01 276.9105 1990-05-01 01:00:00
# 2 5.125 60 1990-05-01 276.8863 1990-05-01 01:00:00
# 3 5.250 60 1990-05-01 276.8621 1990-05-01 01:00:00
# 4 5.375 60 1990-05-01 276.8379 1990-05-01 01:00:00
# 5 5.500 60 1990-05-01 276.8142 1990-05-01 01:00:00
# 6 5.625 60 1990-05-01 276.7913 1990-05-01 01:00:00

aggdf <- aggregate(value ~ x + y + day, mdf, FUN=mean)
aggdf <- with(aggdf, aggdf[order(x,y),])     # RE-ORDER BY X
row.names(aggdf) <- NULL                     # RESET ROW NAMES

head(aggdf, 12)
#        x  y        day    value
# 1  5.000 60 1990-05-01 278.2488
# 2  5.000 60 1990-05-02 280.1225
# 3  5.000 60 1990-05-03 280.3909
# 4  5.000 60 1990-05-04 280.4029
# 5  5.125 60 1990-05-01 278.2514
# 6  5.125 60 1990-05-02 280.1049
# 7  5.125 60 1990-05-03 280.3789
# 8  5.125 60 1990-05-04 280.4211
# 9  5.250 60 1990-05-01 278.2529
# 10 5.250 60 1990-05-02 280.0871
# 11 5.250 60 1990-05-03 280.3648
# 12 5.250 60 1990-05-04 280.4365