Reputation: 1275
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:
deparse(substitute(x))
trick does not work inside this kind of function call.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
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
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