2013-07-24 3 views
25

Есть ли способ использовать mapply для двух векторов для создания именованного списка? Первый вектор будет иметь тип character и содержать имена, используемые для списка, а второй - значения.Создание именованного списка из двух векторов (имена, значения)

До сих пор единственное решение, у меня есть:

> dummyList = list() 
> addToList <- function(name, value) { 
+ dummyList[[name]] <- value 
+ } 
> mapply(addToList, c("foo", "bar"), as.list(c(1, 2)) 
$foo 
`1` 

$bar 
`2` 

Это кажется довольно надуманным решением, но я не могу понять, как это сделать иначе. Проблемы у меня с ней:

  1. Это требует создания dummyListdummyList, хотя никогда не изменяется, и является пустой список после вызова mapply.

  2. Если числовой вектор, c(1, 2), не преобразован в список, то результатом вызова mapply является именованный вектор удвоений.

Чтобы обойти проблему 2, я всегда могу просто позвонить mapply на двух векторов, а затем вызвать as.list на результат, но мне кажется, что там должен быть способ непосредственного создания списка, величина которых в вектор.

ответ

46

Вы можете использовать setNames()

setNames(as.list(c(1,2)), c("foo", "bar")) 

(для списка) или

setNames(c(1,2), c("foo", "bar")) 

(для вектора)

+2

спасибо. Я не знал о функции 'setNames' и отлично подходит для моих целей. Из любопытства, есть ли способ сделать это, используя 'lapply', о котором вы знаете? Кажется возможным, поскольку 'lapply' может возвращать списки. –

+0

Что вы подразумеваете под "использованием' lapply' "? Вы хотите выполнить ту же задачу, используя 'lapply'? (Если это так, почему? Как упражнение по программированию? Больше контекста было бы полезно.) Если вы хотите сделать что-то еще, отредактируйте свой вопрос или спросите нового? –

8

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

Просто ради любопытства, есть своего рода «скрытый» особенность в mapply, что позволит этому:

x <- letters[1:2] 
y <- 1:2 
mapply(function(x,y) { y }, x, y, SIMPLIFY = FALSE,USE.NAMES = TRUE) 
$a 
[1] 1 

$b 
[1] 2 

отмечая, что документация USE.NAMES говорит:

USE.NAMES логический ; используйте имена, если у первого ... аргумента есть имена, или , если это вектор-символ, используйте этот символьный вектор в качестве имен.

+1

Я не думаю, что это такой загадочный случай использования, просто вырожденный. Мне нужно было объединить две двойные массивы с какими-то столбцами row.names, которые автоматически не были получены USE.NAMES, поэтому мне пришлось передавать в row.names (x) вручную в качестве аргумента функции, которая doesn 't использовать: 'f = function (n, x, y) {if (y> 0) {-1 * x} else {x}}; r = mapply (f, row.names (x), x, y, SIMPLIFY = F, USE.NAMES = T) '. 'Data.frame (unlist (r))' завершил задание. Спасибо, что указали эту функцию! –

Смежные вопросы