mzuba
mzuba

Reputation: 1275

Assign names to list elements where name = function pass object name

As part of my project I want to program a function that assigns names to list elements that do not have names. The name should equal the name of the variable.

Here is an example:

returnNamedListofDataFrames.Test <- function(...) {

  # read inputs in list
  inputs <- list(...)

  # assign names to data frame list elements that have no names
  # ???
  inputs <- inputs %>% setNames(lapply(inputs[(names(inputs) == "") %>% which],
                                       function(x) deparse(substitute(x))))

  # return
  return(inputs = inputs)
}


# input data
a = data.frame(value = 1)
b = data.frame(value = 2)

output <- returnNamedListofDataFrames.Test(c = a, # named element, name should stay "c"
                                           b)     # unnamed element, name should be "b"

expected.output <- list(c = a,
                        b = b)

Here, the output is:

> output
$`X[[i]]`
  value
1     1

$<NA>
  value
1     2

Reasons:

I do not know how to address these issues and welcome any advice.

For reference, output should be:

> expected.output
$c
  value
1     1

$b
  value
1     2

Upvotes: 1

Views: 1517

Answers (2)

akrun
akrun

Reputation: 887153

We can use substitute

f1 <- function(...) {
  v1 <- as.list(substitute(list(...)))[-1L]  

  inputs <- list(...)
  i1 <- names(inputs)
  i2 <- i1 == ""
  if(is.null(i1)) {
     names(inputs) <- v1
   } else names(inputs)[i2] <- v1[i2]


 inputs
 }

f1(c=a, b)
#$c
#    value
#1     1

#$b
#   value
#1     2


f1(a, b)
#$a
#   value
#1     1

#$b
#  value
#1     2

Upvotes: 1

Roland
Roland

Reputation: 132706

Use match.call:

returnNamedListofDataFrames.Test <- function(...) {
  callvars <- as.list(match.call())[-1]
  name <- names(callvars)
  if (is.null(name)) name <- as.character(callvars) else 
    name[name == ""] <- as.character(callvars[name == ""])

  setNames(list(...), name)
}

returnNamedListofDataFrames.Test(c = a, # named element, name should stay "c"
                                 b)

#$c
#  value
#1     1
#
#$b
#  value
#1     2

Upvotes: 2

Related Questions