为什么列表需要通过lapply处理索引的字符

时间:2016-04-25 13:39:21

标签: r debugging lapply

我有以下两个代码段(区别在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

第一按预期工作,但第二会抛出:

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
> 

对我来说另一个令人惊讶的事情是第一个示例在as.character(win.size)个函数中都需要lapply。因此,如果我重写第一个代码而不将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. 为什么第一示例正常工作而第二不是?
  2. ls()是显示功能上下文还是整个程序,或者x变量在哪里?
  3. 为什么第一个示例中需要as.character(win.size)
  4. 如何调试这些错误以及为什么n退出Browse模式?

1 个答案:

答案 0 :(得分:0)

我对列表索引的含义感到困惑,这让您感到困惑。给定未命名的列表:

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

当然,按整数索引,

l[[2]]

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

l[["2"]]

尝试查找名称为&#34; 2&#34;的列表元素。但该列表没有名称,因此它将返回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"]]是其名称"3"的元素,恰好是第一个元素。

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