将名称分配给列表元素,其中name = function pass object name

时间:2017-11-08 09:18:05

标签: r function names

作为我项目的一部分,我想编写一个函数,将名称分配给没有名称的列表元素。 名称应该等于变量的名称。

以下是一个例子:

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)

此处输出为:

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

$<NA>
  value
1     2

理由:

  • setNames函数只接收一个元素,但setNames需要所有元素的名称,因此其中一个是NA。
  • deparse(substitute(x))技巧在这种函数调用中不起作用。

我不知道如何解决这些问题并欢迎任何建议。

供参考,输出应为:

> expected.output
$c
  value
1     1

$b
  value
1     2

2 个答案:

答案 0 :(得分:2)

使用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

答案 1 :(得分:1)

我们可以使用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