在函数中使用 diff() 创建错误而不执行

Using diff() inside a function creating error and not executing

我的可重现数据如下所示-

data <- rnorm(16)
timeStamp <- as.POSIXct("2019-03-18 10:30:00") + 0:15*60
Rf <- xts(x = data, order.by = timeStamp)
colnames(Rf) <- "R"

Rf[4:5]$R <- NA
Rf[8:9]$R <- NA
Rf[13:14]$R <- NA

omit.Rf <- na.omit(Rf)

我的目标是按时间顺序标记连续的系列,下面的代码有效-

diff.omit.Rf <- diff(index(omit.Rf))
diff.omit.Rf <- append(1, diff.omit.Rf)
initNum <- 1
for (i in 1:length(omit.Rf)){
  if (diff.omit.Rf[[i]] == 1){
    omit.Rf$opNum[i] <- initNum
  } else {
    initNum <- initNum + 1
    omit.Rf$opNum[i] <- initNum
  }
}

我得到了这个输出-

                     R              opNum
2019-03-18 10:30:00  0.89262137     1
2019-03-18 10:31:00  0.50428310     1
2019-03-18 10:32:00 -0.00040488     1
2019-03-18 10:35:00  0.10126335     2
2019-03-18 10:36:00  0.48726498     2
2019-03-18 10:39:00  1.05075049     3
2019-03-18 10:40:00 -0.25495699     3
2019-03-18 10:41:00  0.89257782     3
2019-03-18 10:44:00 -1.25474533     4
2019-03-18 10:45:00  0.55393767     4

不幸的是,当我使用相同的代码创建一个函数时,它给了我以下警告并且不执行该函数。

Error in diff.omit.Rf[[i]] : subscript out of bounds

我做的函数的代码-

opTimeFun <- function(dataToDeal){
  diff.data <- diff(index(dataToDeal))
  diff.data <- append(1, diff.data)
  initNum <- 1
  for (i in 1:length(dataToDeal)){
    if (diff.data[[i]] == 1){
      dataToDeal$opNum[i] <- initNum
    } else {
      initNum <- initNum + 1
      dataToDeal$opNum[i] <- initNum
    }
  }
}

有人可以帮忙解决这个问题吗?谢谢

这是一个较短的版本,没有 for 循环,使用 diffcumsum 创建系列。

opTimeFun <- function(temp) {
   cumsum(c(TRUE, diff(index(temp)) > 1))
}

omit.Rf$opNum <- opTimeFun(omit.Rf)
omit.Rf

#                             R opNum
#2019-03-18 10:30:00 -0.1952424     1
#2019-03-18 10:31:00  0.8429390     1
#2019-03-18 10:32:00 -0.2429325     1
#2019-03-18 10:35:00  1.3471985     2
#2019-03-18 10:36:00 -0.7869906     2
#2019-03-18 10:39:00  0.5220991     3
#2019-03-18 10:40:00 -1.9884231     3
#2019-03-18 10:41:00 -1.8417666     3
#2019-03-18 10:44:00  1.5586149     4
#2019-03-18 10:45:00  3.5704500     4

我们可以一步步分解这个函数来了解它是如何工作的。

diff returns 以分钟为单位的时差。

diff(index(omit.Rf))
#Time differences in mins
#[1] 1 1 3 1 3 1 1 3 1

我们将它与 1 分钟进行比较,找出大于 1 分钟的值

diff(index(omit.Rf)) > 1
#[1] FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE

因为 diff returns 值的长度比原始向量小 1,所以我们在向量的开头添加了默认值 TRUE

c(TRUE, diff(index(omit.Rf)) > 1)
#[1]  TRUE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE  TRUE FALSE

现在求这个逻辑向量的累加和,它会在值大于 1 的点递增。

cumsum(c(TRUE, diff(index(omit.Rf)) > 1))
#[1] 1 1 1 2 2 3 3 3 4 4

就原始函数而言,它可以正常工作,但我们需要显式 return 从函数返回对象。所以下面的功能应该可以工作。

opTimeFun <- function(dataToDeal){
  diff.data <- diff(index(dataToDeal))
  diff.data <- append(1, diff.data)
  initNum <- 1
  for (i in 1:length(dataToDeal)){
     if (diff.data[[i]] == 1){
        dataToDeal$opNum[i] <- initNum
     } else {
        initNum <- initNum + 1
        dataToDeal$opNum[i] <- initNum
     }
   }
   return(dataToDeal)
 }

opTimeFun(omit.Rf)