R: Использовать аргументы функции в качестве имен для вспомогательных элементов списка

3 Jota [2013-11-27 07:20:00]

Вот упрощенный пример того, что я пытаюсь сделать

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)

Вот результат:

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

Имена элементов списка основаны на именах, которые я указал при определении функции, а не на фактических входах, используемых в функции. Это имеет смысл, в общем, но я хотел бы знать, как изменить это поведение для конкретной проблемы.

Мой желаемый результат, учитывая входы a и b, будет

$sums
a        b 
1.322028 2.488450 

$products
a            b 
0.0026236813 0.0003054751 

Какими бы ни были входные данные, будь они c(1,2,3,3,3,123) и c(2,1,1,5,7,1) или rnorm(10) и rpois(10), должны быть возвращены на выходе.

Я знаю, как сделать переименование после выполнения функции, но я хочу, чтобы именование произошло внутри функции. Я смотрел на другие вопросы о SO, но у меня ничего не получилось.

Несколько вещей, которые я пробовал без успеха.

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)
}

Кажется, мне, возможно, придется использовать get или assign или match.call, но я вне этой лиги.

Я чувствую себя немного похожим на dunce, читающего некоторые из этих страниц справки. Если я не знаю достаточно, чтобы понять страницы справки, ну, я не так хорош в R, как я и думал.

function list r names


1 ответ


2 Решение Ricardo Saporta [2013-11-27 08:14:00]

используйте substitute для захвата имен, затем setNames для установки.

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)

вы можете поместить setNames прямо в вызов list() выше, но это может привести к слишком громоздкому чтению кода