簡體   English   中英

如何在沒有循環或mapply的R中的向量的不同間隔上使用相同的函數?

[英]How to use the same function on different intervals of a vector in R without loops or mapply?

假設我有一個數據框,如

         Date    Value
1  2014-04-14   830.61
2  2014-04-11   815.69
3  2014-04-10   833.08
4  2014-04-09   872.18
5  2014-04-08   851.96
6  2014-04-07   845.04
7  2014-04-04   865.09
8  2014-04-03   888.77
9  2014-04-02   890.90
10 2014-04-01   885.52

我們把它命名為DF。 假設我已經定義了索引號的最小值和最大值。

minvals<-c(1,2,3)
maxvals<-c(5,7,10)

我想為每個區間處理一個函數(即值列的平均值或標准差)。 例如,取第一個間隔的平均值。

DF[minvals[1]:maxvals[1],"Value"]

         Date    Value
1  2014-04-14   830.61
2  2014-04-11   815.69
3  2014-04-10   833.08
4  2014-04-09   872.18
5  2014-04-08   851.96

mean(DF[minvals[1]:maxvals[1],"Value"])
#840.704

也適用於其他小型和小型。 首先想到的是mapply。 但是因為我的數據包含了數千個這樣的小數和最大值。 是否有可能以有效的方式做到這一點?

ps實際上,它與滾動平均值非常相似,但我的日期列僅包括工作日,因此我不確定zoo包的rollmean函數是否可以處理這個問題。 無論如何,假設我的時間間隔也不規律。

試試data.table

DFvec <- DF$Value
Ints <- data.frame(MIN = c(1,2,3), MAX = c(5,7,10))
library(data.table)
setDT(Ints)[, MEAN := mean(DFvec[MIN:MAX]), by = c("MIN", "MAX")]
Ints
##    MIN MAX     MEAN
## 1:   1   5 840.7040
## 2:   2   7 847.1733
## 3:   3  10 866.5675

其他方式:

minvals = as.integer(minvals)
maxvals = as.integer(maxvals)
lenvals = maxvals - minvals + 1L
ix  = data.table:::vecseq(minvals, lenvals, sum(lenvals))
grp = rep(seq_along(lenvals), lenvals)

setDT(DF[ix, ])[, list(Value=mean(Value)), by=grp]
#    grp    Value
# 1:   1 840.7040
# 2:   2 847.1733
# 3:   3 866.5675

這是mapply解決方案。 如果這太慢了(給出一個可重現的問題大小示例),你可以用data.table做一些聰明的事情或使用Rcpp。

x <- DF[["Value"]] #avoid data.frame subsetting in a loop
mapply(function(i1, i2) mean.default(x[i1:i2]), minvals, maxvals)

1e5間隔的基准:

library(microbenchmark)
set.seed(42)
i <- sample(1:3, 1e5, TRUE)
minvals<-c(1,2,3)[i]
maxvals<-c(5,7,10)[i]
microbenchmark(mapply(function(i1, i2) mean.default(x[i1:i2]), minvals, maxvals), times=10)

Unit: milliseconds
                                                             expr      min       lq   median       uq      max neval
mapply(function(i1, i2) mean.default(x[i1:i2]), minvals, maxvals) 446.0529 473.4267 489.2375 523.2335 595.5536    10

這是幾種方法。 從描述中不清楚效率在這里真的很重要,可讀性可能更重要:

# they all use this:
DF.Value <- DF$Value

# 1
sapply(seq_along(minvals), function(i) mean(DF.Value[minvals[i]:maxvals[i]]))

# 2
f <- function(minvals, maxvals) mean(DF.Value[minvals:maxvals])
mapply(f, minvals, maxvals)

# 3 - this one assumes that minvals equals seq_along(minvals) which is true in example
library(zoo)
w <- maxvals - minvals + 1
rollapply(DF.Value, w, mean, align = "left")[minvals]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM