如何计算一个变量每10行的平均值

3

我有一些数据集是每1分钟收集的,但我必须用10分钟数据的平均值替换数据。所以我有以下 R 代码。

for(k in 1:(length(temp[,1])/10)){
  temp2[k,1]<-temp[1,1]
  temp2[k,2]<-temp[k*10,2]
  temp2[k,3]<-mean(na.omit(as.numeric(temp[((k-1)*10+1):k*10,3])))
}

然而,这段代码的效率太低了。 还有一个问题。由于某些数据缺失,时间变量不总是连续的。我必须计算每个真实10分钟的数据(例如从2014年1月1日00:00到2014年1月1日00:10),无论这10分钟内有多少个观测值。因此循环进入到
  tmp<-na.omit(temp[temp[,2]>(st+600*(k-1)) & temp[,2]<=(st+600*k),])
  temp2[k,1]<-tmp[1,1]
  temp2[k,2]<-st+600*k
  temp2[k,3]<-mean(na.omit(as.numeric(tmp[,3])))

这是不可承受的。它不能有效地处理类似“某些月份缺失”的情况。那么,在效率不低的情况下,我该如何在R中解决这个问题呢?

原始数据:

Time  Var1
2014-01-01 00:01  10
2014-01-01 00:02  12
2014-01-01 00:03  43

...
2014-01-01 00:10  52

期望输出:

Time  Var1
2014-01-01 00:10  (mean of every 10 mins)
2014-01-01 00:20  (mean of every 10 mins)
...

你能提供一些数据和期望的输出吗? - DatamineR
你需要使用 dput() 函数将数据的一个经过编辑的子集转储出来。可以查看 zoo::rollmean() 函数和 tseries 包。 - smci
3个回答

4

看一下xts包,特别是使用endpointsperiod.apply函数。

假设你可以将数据作为一个xts对象获取(在这种情况下称为xt.data),那么以下内容将起作用。

# example data
times <- seq(Sys.time()-50000,Sys.time(),by=60)
mydt <- data.frame(time = times[sample(seq_along(times),size=300)], test = runif(300)) 
xt.data <- as.xts(mydt[,2], order.by= mydt[['time']])

period.apply(xt.data, endpoints(xt.data,'minutes',10),mean)

2

请看一下?cut.POSIXt?seq.POSIXtround.POSIXtcutseq 函数允许将间隔设置为"10 min"。但很遗憾,round函数似乎没有这个不错的功能。您可以乘以10,四舍五入到最近的“min”,然后再除以10,但我还没有尝试过。


1
如果您记住有一种名为POSIXlt的时间格式,它使得操作每个组件变得轻松,则相对容易。我在这里所做的是使用POSIXct格式读取数据(因为您无法使用POSIXlt进行读取),将其转换为POSIXlt,然后按照10分钟的组进行分组,再进行转换并聚合。这应该运行得非常快速。
dat <- read.table(text = 'time, y
                          2014-01-01 00:01, 10
                          2014-01-01 00:02, 12
                          2014-01-01 00:22, 43', 
                          header = TRUE, sep = ',', colClasses = c('POSIXct', 'numeric'))
dat$time <- as.POSIXlt(dat$time)
dat$time[[2]] <- floor(dat$time[[2]] / 10) * 10
dat$time <- as.POSIXct(dat$time)
aggregate(y ~ time, data = dat, mean)

作为旁注,你说的是每10分钟替换一次,而不是聚合。在这种情况下,聚合行将变成:
y$time <- ave(y, time)

如果您想保留原始时间和所有其他数据,但只是通过10分钟的平均值进行替换,您可以在read.table之后用以下内容替换:

dat$time <- as.POSIXlt(dat$time)
g <- floor(dat$time[[2]] / 10) * 10
dat$y <- ave(y, g)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接