【问题标题】:Using diff() inside a function creating error and not executing在函数中使用 diff() 会产生错误而不执行
【发布时间】:2020-04-14 15:17:42
【问题描述】:

我的可重现数据看起来像这样-

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
    }
  }
}

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

【问题讨论】:

    标签: r xts zoo


    【解决方案1】:

    这是一个没有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 以分钟为单位返回时差。

    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 返回的值比原始向量的长度小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)
    

    【讨论】:

    • 你能解释一下cumsum代码吗?如果可能的话,你能反思一下我的代码中的错误吗?我在编码方面非常新手,只想学习。主要是,在我的代码中,我不明白为什么相同的代码在函数外部工作而不在内部工作。
    • @user11841472 我添加了一些对代码的解释以及您的代码不起作用的原因。希望对您有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2021-04-26
    • 1970-01-01
    • 2019-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多