【问题标题】:rollapply with function rle(x)使用函数 rle(x) 滚动应用
【发布时间】:2014-01-24 06:35:44
【问题描述】:

我有时间序列数据作为 data.table 类,每一列(观察点)都有我想在滑动窗口(30 宽度)内计算它们的值。 我尝试使用 rle(sort(x)) 来计算 rollapply 中的每个值,但它不起作用。

例如,如果我有如下表,

dt <- data.frame(v1=c(1,0,1,4,4,4,4,4),v2=c(1,1,1,4,3,3,3,3),
          v3=c(0,1,1,3,3,3,3,2),v4=c(1,1,0,3,3,3,3,3),
       v5=c(1,1,1,5,5,5,5,5))

我试过这样;

rollapply(dt, 3, function(x) {rle(sort(x))$values; rle(sort(x))$length})

但结果就是没有意义。 请给我一些方向...

【问题讨论】:

  • 我在上面没有看到任何data.table。但更重要的是,不清楚您想要什么 - 请提供所需的输出。
  • 对不起,不清楚的问题。所需的输出是对于每个滑动窗口,我想用出现次数(计数)对值进行排序。我可以把我的 dt 变成 dt1

标签: r data.table zoo rollapply


【解决方案1】:

解决方案 1 假设目标是获得 3 个值的滚动计数,请尝试以下操作:

m <- as.matrix(dt)
levs <- sort(unique(c(m)))
f <- function(x) table(factor(x, levs))
r <- rollapply(m, 3, f)

这里levs 是 0、1、...、5,因此对于函数的每个应用,我们将得到一个 6 长的向量,其中包含 0、1、...、5 的计数。有 5 个输入列,因此对每列应用这样的函数会得到 5 * 6 = 30 列的输出。

请注意,rollapply 适用于矩阵或动物园对象,而不是数据框,因此我们对其进行了转换。此外,为了确保每个函数应用程序输出相同长度的向量,我们将每个输入转换为具有相同级别的因子。

注意:

ra <- array(r, c(6, 6, 5))

给出一个 3d 数组,其中 ra[,,i] 是由rollapply(dt[, i], 3, f) 形成的矩阵。也就是说,在矩阵ra[,,i] 中,f 在第 i 列上的每个应用都有一行,并且该行中的列计算 0、1、...、5 的数量。

另一种可能性是给出与结果列表的组件相同的 5 个矩阵(每个输入列一个):

lapply(dt, rollapply, 3, f)

例如,考虑以下情况。输出的第 1 行表示 f 在 dt[,1] 上的第一个应用程序有一个 0、两个 1 并且没有其他值。这也可以从r[,,1] 或从 lapply(dt, rollapply, 3, f)[[1]]

> rollapply(dt[, 1], 3, f)
     0 1 2 3 4 5
[1,] 1 2 0 0 0 0  <- dt[1:3,1] has 1 zero and 2 ones
[2,] 1 1 0 0 1 0  <- dt[2:4,1] has 1 zero and 1 one and 1 four, etc.
[3,] 0 1 0 0 2 0
[4,] 0 0 0 0 3 0
[5,] 0 0 0 0 3 0
[6,] 0 0 0 0 3 0

解决方案 2

这表示查看输出的单元格 1,1,dt[1:3,1] 中有一个 0 和两个 1。查看输出的 2,1 单元格,我们看到 dt[2:4,1] 中有一个 0、一个 1 和 1 四个等。

> g <- function(x) { tab <- table(x); toString(paste(names(tab), tab, sep = ":")) }
> sapply(dt, rollapply, 3, g) # or rollapply(m, 3, g) where m was defined in solution 1
     v1              v2              v3         v4              v5        
[1,] "0:1, 1:2"      "1:3"           "0:1, 1:2" "0:1, 1:2"      "1:3"     
[2,] "0:1, 1:1, 4:1" "1:2, 4:1"      "1:2, 3:1" "0:1, 1:1, 3:1" "1:2, 5:1"
[3,] "1:1, 4:2"      "1:1, 3:1, 4:1" "1:1, 3:2" "0:1, 3:2"      "1:1, 5:2"
[4,] "4:3"           "3:2, 4:1"      "3:3"      "3:3"           "5:3"     
[5,] "4:3"           "3:3"           "3:3"      "3:3"           "5:3"     
[6,] "4:3"           "3:3"           "2:1, 3:2" "3:3"           "5:3"     

添加:附加讨论和解决方案 2。

【讨论】:

  • 感谢您的回答。但真的很难解释结果。我真正想要得到的是 - 如果我只是使用 5 宽度滑动窗口使用上面的 dt 数据。对于第一个滑动窗口的 v1 列,1 有 2 个计数,0 有 1,4 有 2,在第二个滑动窗口中,1 有 1,0 有 1,4 有 3 个计数。等等。所以当我简单地将 rle(sort(x)) x 作为简单向量运行时,你会得到带有总计数的结果排序值。这就是我想在我的滑动窗口中拥有的,但是......我不知道为什么 rle 函数不能很好地应用在 rollapply 函数中
  • 问题中代码的问题在于,给rollapply 的函数会根据输入值返回不同长度的输出,因此它无法将结果变成矩形。我添加了额外的讨论和第二个解决方案。
  • 这非常有帮助。我会尽量消化所有内容,如果我对您的方法还有其他问题,请告诉您。
  • 再次感谢您的帮助。我还可以添加一些代码来提取每个滑动窗口中的值及其最大计数吗?
  • 在解决方案 2 中,将 table(x) 替换为 sort(table(x)),然后值和计数将按计数顺序排列,因此最后一个将是最大值。如果您只想要最大值及其计数,请将table(x) 替换为tail(sort(table(x)), 1)。根据您的需要,还有其他变化。只需适当修改g即可。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-12-13
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
  • 2021-08-07
  • 1970-01-01
相关资源
最近更新 更多