0

I have following two code snippets (the difference is just in names position):

1st:

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

2nd:

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 is working as expected but the 2nd throws:

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

when it comes to this line:

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

The error message is same as if cor were called only with one argument e.g.:

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

Based on suggestions about debugging apply functions I've set options(error = browser) to see what happens. What is surprising for me is that there is no x variable in function context and I cannot move in code (pressing n quits 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
> 

Another surprising thing for me is that 1st example requires as.character(win.size) in both lapply functions. So if I rewrite the 1st code without casting win.size to 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]]) })

I get the error:

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

when it comes to this line line:

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

Setting options(error = browser) did not helped again and as previously there is no x variable:

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

Questions:

  1. Why is 1st example working and 2nd is not?
  2. Is ls() showing the function context or whole program or where is my x variable?
  3. Why is as.character(win.size) required in 1st example?
  4. How can I debug those errors and why n quits Browse mode?
Community
  • 1
  • 1
Wakan Tanka
  • 7,542
  • 16
  • 69
  • 122

1 Answers1

0

I'm a little confused as to what it is about list indexing that is confusing you. Given an unnamed list:

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

Surely, indexing by an integer,

l[[2]]

gives you the second element of the list, while indexing by a character,

l[["2"]]

attempts to find the list element whose name is "2". But the list has no names, so it will return NULL.

In your second example your first lapply creates an unnamed list and then you try to index it by name. Surely that can't work, right?

The same principle works in reverse. If I do give the list names:

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

$`2`
[1] 1 2 3

$`1`
[1] 1 2 3 4

...now l[[3]] is still the third element of the list, but l[["3"]] is the element whose name is "3", which happens to be the first element.

If these sorts of basic indexing issues are confusing you, some basic R tutorials might be a good place to spend some time.

joran
  • 169,992
  • 32
  • 429
  • 468