Question

Here is a simplified example of what I am trying to do

set.seed(1)
a <- rnorm(10)
b <- rnorm(10)

asdf<-function(vec1,vec2){
  mylist <- list(sums = c(vec1 = sum(a), vec2 = sum(b)),
                 products = c(vec1 = prod(a), vec2 = prod(b)))
  return(mylist)
}

asdf(a,b)

Here is the output:

$sums
vec1     vec2 
1.322028 2.488450 
$products
vec1         vec2 
0.0026236813 0.0003054751 

The names of the list elements are based on the names I specified when defining the function, not the actual inputs used in the function. This makes sense, in general, but I would like to know how to change this behavior for a specific problem

My desired output, given inputs a and b would be

$sums
a        b 
1.322028 2.488450 

$products
a            b 
0.0026236813 0.0003054751 

Whatever the inputs are, be they c(1,2,3,3,3,123) and c(2,1,1,5,7,1) or rnorm(10) and rpois(10), should be returned in the output.

I know how to do the renaming after the function is done, but I want the naming to happen within the function. I've been looking at some other questions on SO, but haven't had anything work out quite right.

A few things I've tried without success.

asdf<-function(vec1,vec2){
  name1<- deparse(substitute(vec1))
  name2<- deparse(substitute(vec2))
  mylist <- list(sums = c(name1 = sum(a), name2 = sum(b)),
                 products = c(name1 = prod(a), name2 = prod(b)))
  return(mylist)
}

asdf<-function(vec1,vec2){ 
  mylist <- list(sums = c(name1 = sum(a), name2 = sum(b)),
                 products = c(name1 = prod(a), name2 = prod(b)))
  assign(names(mylist(vec1,vec2)$sums,
         c(deparse(substitute(vec1)),deparse(substitute(vec2)))))
  return(mylist)
}

It seems I may need to use get or assign or match.call, but I'm out of my league here.

I feel a bit like a dunce reading some of these help pages. If I don't know enough to understand the help pages, well, I'm not nearly as good at R as I thought I was.

Was it helpful?

Solution

use substitute to capture the names, then setNames to setthem.

asdf<-function(vec1,vec2){
  nms <- as.character(c(substitute(vec1), substitute(vec2)))

  mylist <- list(sums = c(vec1 = sum(a), vec2 = sum(b)),
                 products = c(vec1 = prod(a), vec2 = prod(b)))

  # return
  lapply(mylist, setNames, nms)
}

asdf(a,b)

you can put the setNames right into the list() call above, but that might the code too cumbersome to read

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top