Question

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

Was it helpful?

Solution

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')
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top