【问题标题】:why lists requires characters for indexing when they are processed via lapply为什么列表在通过 lapply 处理时需要用于索引的字符
【发布时间】:2016-04-25 13:39:21
【问题描述】:

我有以下两个代码sn-ps(区别只是在names位置):

第一:

library(zoo)
vec             <- rep(c(rep(5,10), rep(2,10)), 10)
win.size        <- c(2, 4, 5, 10, 20, 30)
vec.avgs        <- lapply(win.size, function(x) { rollapply(vec, width = x,  by = x,  FUN = mean, align = "left") })
names(vec.avgs) <- win.size
vec.rep         <- lapply(as.character(win.size), function(x) { rep(vec.avgs[[x]], each=x) })
names(vec.rep)  <- win.size
res             <- lapply(as.character(win.size), function(x) { cor(vec[1:length(vec.rep[[x]])], vec.rep[[x]]) })

第二次:

library(zoo)
vec             <- rep(c(rep(5,10), rep(2,10)), 10)
win.size        <- c(2, 4, 5, 10, 20, 30)
vec.avgs        <- lapply(win.size, function(x) { rollapply(vec, width = x,  by = x,  FUN = mean, align = "left") })
vec.rep         <- lapply(as.character(win.size), function(x) { rep(vec.avgs[[x]], each=x) })
res             <- lapply(as.character(win.size), function(x) { cor(vec[1:length(vec.rep[[x]])], vec.rep[[x]]) })
names(vec.avgs) <- win.size
names(vec.rep)  <- win.size

1st 工作正常,但 2nd 抛出:

Error in cor(vec[1:length(vec.rep[[x]])], vec.rep[[x]]) : 
  supply both 'x' and 'y' or a matrix-like 'x'

说到这一行:

res <- lapply(as.character(win.size), function(x) { cor(vec[1:length(vec.rep[[x]])], vec.rep[[x]]) }) 

错误消息与仅使用一个参数调用 cor 相同,例如:

> cor(vec,)
Error in cor(vec, ) : supply both 'x' and 'y' or a matrix-like 'x'

基于suggestions 关于调试apply 函数,我设置了options(error = browser) 以查看会发生什么。令我惊讶的是函数上下文中没有x 变量,我无法在代码中移动(按n 退出Browse):

> lapply(as.character(win.size), function(x) { cor(vec[1:length(vec.rep[[x]])], vec.rep[[x]]) })
Error in cor(vec[1:length(vec.rep[[x]])], vec.rep[[x]]) : 
  supply both 'x' and 'y' or a matrix-like 'x'
Called from: stop("supply both 'x' and 'y' or a matrix-like 'x'")
Browse[1]> ls()
[1] "vec"      "vec.avgs" "vec.rep"  "win.size"
Browse[1]> x
Error during wrapup: object 'x' not found
Browse[1]> n
> 

另一个令我惊讶的是,第一个示例在两个lapply 函数中都需要as.character(win.size)。因此,如果我重写 1st 代码而不将 win.size 转换为 characters:

vec             <- rep(c(rep(5,10), rep(2,10)), 10)
win.size        <- c(2, 4, 5, 10, 20, 30)
vec.avgs        <- lapply(win.size, function(x) { rollapply(vec, width = x,  by = x,  FUN = mean, align = "left") })
names(vec.avgs) <- win.size
vec.rep         <- lapply(win.size, function(x) { rep(vec.avgs[[x]], each=x) })
names(vec.rep)  <- win.size
res             <- lapply(win.size, function(x) { cor(vec[1:length(vec.rep[[x]])], vec.rep[[x]]) })

我得到错误:

Error in vec.avgs[[x]] : subscript out of bounds
Called from: FUN(X[[i]], ...)

当谈到这一行时:

vec.rep <- apply(win.size, function(x) { rep(vec.avgs[[x]], each=x) })

设置 options(error = browser) 并没有再次帮助,因为之前没有 x 变量:

> lapply(win.size, function(x) { rep(vec.avgs[[x]], each=x) })
Error in vec.avgs[[x]] : subscript out of bounds
Called from: FUN(X[[i]], ...)
Browse[1]> ls()
[1] "vec"      "vec.avgs" "win.size"
Browse[1]> n
>

问题:

  1. 为什么 1st 示例有效而 2nd 无效?
  2. ls() 是否显示函数上下文或整个程序,或者我的 x 变量在哪里?
  3. 为什么在第一个示例中需要as.character(win.size)
  4. 如何调试这些错误以及为什么n 退出Browse 模式?

【问题讨论】:

    标签: r debugging lapply


    【解决方案1】:

    对于让您感到困惑的列表索引是什么,我有点困惑。给定一个未命名的列表:

    l <- list(1:2,1:3,1:4)
    > names(l)
    NULL
    

    当然,按整数索引,

    l[[2]]
    

    为您提供列表的第二个元素,同时按字符进行索引,

    l[["2"]]
    

    尝试查找 name 为“2”的列表元素。但是这个列表没有名字,所以它会返回NULL

    在您的第二个示例中,您的第一个 lapply 创建了一个未命名列表,然后您尝试按名称对其进行索引。肯定不行吧?

    同样的原理反过来也起作用。如果我确实给出了列表名称:

    > names(l) <- 3:1
    > l
    $`3`
    [1] 1 2
    
    $`2`
    [1] 1 2 3
    
    $`1`
    [1] 1 2 3 4
    

    ...现在l[[3]] 仍然是列表的第三个元素,但l[["3"]]name"3" 的元素,恰好是第一个元素。

    如果这些基本的索引问题让您感到困惑,一些基本的 R 教程可能是花一些时间的好地方。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-20
      • 1970-01-01
      • 2020-05-14
      • 2011-05-10
      • 2014-11-20
      相关资源
      最近更新 更多