1

Just for example, I have a dataframe with columns: name, n, mean and sd. How do I extract and then save the elements of a list into a single rda file. The file should contain the generated datasets and not the list.

random.r <- function(df, filename) {
  save.random <- function(name, n, mean, sd) {
    rn <- rnorm(n=n, mean=mean, sd=sd)
    assign(deparse(name), rn)
  }

  rlist <- sapply(1:nrow(df), function(x) 
    save.random(df$name[x], df$n[x],df$mean[x],df$sd[x],simplify = FALSE))
  save(list = rlist, file = paste(filename,".Rda",sep=""), envir = .GlobalEnv)    
}

Cheers

jbaums
  • 27,115
  • 5
  • 79
  • 119
geodex
  • 1,219
  • 3
  • 13
  • 22
  • Are your code blocks attempts at doing what you're requesting help with? Not sure what you intend `random.r` to do, exactly. – jbaums Feb 16 '14 at 09:17
  • @jbaums yes, just modified the code to make it simpler as it involved a lot of equations. i would want to have 'save' to include only the rlist elements and not the list itself. – geodex Feb 16 '14 at 09:58
  • @jbaums my apologies. have edited the code to reflect just one function. Adjusted the encapsulation as random.r and rlist appears to be different functions. rlist is within random.r – geodex Feb 16 '14 at 10:01
  • Thanks for correcting the code - I've edited my answer, which should now solve your problem. There were a couple of issues with your code: elements of `rlist` were not being named correctly; the vector of element names to save was not specified correctly; and the search environment was wrong. – jbaums Feb 16 '14 at 21:44
  • @jbaum lack of sleep makes me dizzy and confused – geodex Feb 17 '14 at 07:08

1 Answers1

3

The trick is to tell R where to find the objects referred to in save. To do this, provide the list itself as an environment:

save(list=names(rlist), file=..., envir=as.environment(rlist))

Note also that list must be a vector of object names, so this should be names(rlist), not simply rlist, since the latter is a list of numeric vectors.

The following is a modification of your random.r, which works as you had intended. At the end of this post I also provide simplified code that achieves the same.

random.r <- function(df, filename) {
  save.random <- function(name, n, mean, sd) {
    rnorm(n=n, mean=mean, sd=sd)
  }

  rlist <- setNames(lapply(1:nrow(df), function(x) {
    save.random(df$name[x], df$n[x], df$mean[x], df$sd[x])
  }), df$name)
  save(list = names(rlist), file = paste0(filename, ".rda"), 
       envir = as.environment(rlist))    
}

The key changes above are the specification of names(rlist) as the list (vector) of element names that you want to save, and as.environment(rlist) as the environment in which you want R to search for objects with those names. Note also that I've used setNames to correctly assign elements of df$name as the names of the resulting elements of rlist.

A simplified version would be:

rlist <- setNames(mapply(rnorm, d$n, d$mean, d$sd), d$name)
save(list=names(rlist), file='~/../Desktop/foo.rda', 
     envir=as.environment(rlist))

where d is your data.frame. Here, mapply is a handy shortcut; it steps through the vectors d$n, d$mean and d$sd simultaneously, performing rnorm each time.

The simplified code can of course be wrapped into a function if you require, e.g.:

f <- function(x, filename) {
  rlist <- setNames(mapply(rnorm, x$n, x$mean, x$sd), x$name)
  save(list=names(rlist), file=paste0(filename, '.rda'), 
       envir=as.environment(rlist))
}

d <- data.frame(name=LETTERS, n=sample(100, 26), mean=runif(26), sd=runif(26),
                stringsAsFactors=FALSE)

f(d, '~/../Desktop/foo')
jbaums
  • 27,115
  • 5
  • 79
  • 119