4

I have a time series (x,y,z and a) in a list name called dat.list. I would like to apply a function to this list using lapply. Is there a way that I can print the element names i.e., x,y,z and a after each iteration is completed in lapply. Below is the reproducible example.

## Create Dummy Data

x <- ts(rnorm(40,5), start = c(1961, 1), frequency = 12)
y <- ts(rnorm(50,20), start = c(1971, 1), frequency = 12)
z <- ts(rnorm(50,39), start = c(1981, 1), frequency = 12)
a <- ts(rnorm(50,59), start = c(1991, 1), frequency = 12)

dat.list <- list(x=x,y=y,z=z,a=a)

## forecast using lapply

abc <- function(x) {
  r <- mean(x)
  print(names(x))
  return(r)
}

forl <- lapply(dat.list,abc)

Basically, I would like to print the element names x,y,z and a every time the function is executed on these elements. when I run the above code, I get null values printed.

forecaster
  • 1,084
  • 1
  • 14
  • 35
  • You may be looking for `deparse(substitue(x))`. See this question: http://stackoverflow.com/questions/10520772/in-r-how-to-get-an-objects-name-from-the-object-itself – Jota Jan 01 '15 at 01:07
  • Nope. this is one time when deparse(substitute(.)) is not the answer. – IRTFM Jan 01 '15 at 01:34
  • 1
    Closing this as a duplicate, but I think it should stay around (not be deleted) since the question is presented clearly and with a clear title. – A5C1D2H2I1M1N2O1R2T1 Jan 01 '15 at 05:00

2 Answers2

4

The item names do not get passed to the second argument from lapply, only the values do. So if you wanted to see the names then the calling strategy would need to be different:

> abc <- function(nm, x) {
+   r <- mean(x)
+   print(nm)
+   return(r)
+ }
> 
> forl <- mapply(abc, names(dat.list), dat.list)
[1] "x"
[1] "y"
[1] "z"
[1] "a"
IRTFM
  • 258,963
  • 21
  • 364
  • 487
4

You can use some deep digging (which I got from another answer on SO--I'll try to find the link) and do something like this:

abc <- function(x) {
  r <- mean(x)
  print(eval.parent(quote(names(X)))[substitute(x)[[3]]])
  return(r)
}

forl <- lapply(dat.list, abc)
# [1] "x"
# [1] "y"
# [1] "z"
# [1] "a"
forl
# $x
# [1] 5.035647
# 
# $y
# [1] 19.78315
# 
# $z
# [1] 39.18325
# 
# $a
# [1] 58.83891

Our you can just lapply across the names of the list (similar to what @BondedDust did), like this (but you lose the list names in the output):

abc <- function(x, y) {
  r <- mean(y[[x]])
  print(x)
  return(r)
}

lapply(names(dat.list), abc, y = dat.list)
A5C1D2H2I1M1N2O1R2T1
  • 190,393
  • 28
  • 405
  • 485
  • Perfect, this is exactly what I wanted. – forecaster Jan 01 '15 at 03:43
  • Only one problem. You would need to adjust it to work without `lapply`. The capital `X` throws an error `abc(1:5) #Error in eval(expr, envir, enclos) : object 'X' not found` – Rich Scriven Jan 01 '15 at 03:51
  • @RichardScriven, given the title ofthe question and the nature ofthe problem, I don't see how it's a problem.... – A5C1D2H2I1M1N2O1R2T1 Jan 01 '15 at 03:55
  • @AnandaMahto, I installed new R version, and the `print(eval.parent(quote(names(X)))[substitute(x)[[3]]])` no longer works and throws the following error, `Error in eval.parent(quote(names(X)))[substitute(x)[[3]]] : invalid subscript type 'symbol' `, is there a work around on this? – forecaster May 18 '15 at 19:48
  • 1
    I offered one solution [here](http://stackoverflow.com/questions/30330104/print-list-names-while-iterating-in-lapply-not-working-in-3-2/30330866#30330866), cross-commenting here for reference only. – r2evans May 19 '15 at 16:14