繁体   English   中英

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

[英]Averaging every n columns and keep first two columns in the new data.frame in 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)来直接计算每日平均值,以最大程度地减少共cobind任何可能误差

代替

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

尝试

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

一步就能为您带来理想的结果。 另外,由于不需要知道数据帧的长度,因此可以最大程度地减少出错的机会。 tab[-(1:2)]表示“ tab除前两个外的所有列”。

经典教科书的情况下,由于需要进行诸如分组聚合(特别是平均)之类的操作,因此无法以宽格式存储数据。 考虑将数据分解为长格式,并按日期将每个XY分组汇总:

DATA (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)

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM