Как давать имена переменным на лету?


96

Можно ли на лету создавать новые имена переменных?

Я хотел бы читать фреймы данных из списка в новые переменные с числами в конце. Что-то вроде orca1, orca2, orca3 ...

Если я попробую что-то вроде

paste("orca",i,sep="")=list_name[[i]]

Я получаю эту ошибку

target of assignment expands to non-language object

Есть ли другой способ обойти это?


10
Пока мы выдаем теги r-faq, давайте дадим ссылку (FAQ 7.21: cran.r-project.org/doc/FAQ/… )
Бен Болкер,

Ответы:


118

Использование assign:

assign(paste("orca", i, sep = ""), list_name[[i]])

28
Вот как это сделать. Здесь есть мета-вопрос: «Должен ли я сделать это?» Ответ почти всегда отрицательный. Именованные элементы в списке почти всегда предпочтительнее.
Ari B. Friedman

26
Ответ почти всегда отрицательный, за исключением тех случаев, когда это не так.
Шейн

9
Да, конечно. Но большинство людей, ищущих этот ответ, делают это не из-за того, что отклонили список для своей заявки.
Ари Б. Фридман

@Ari B. Friedman Я генерирую имена переменных для наборов данных, которые сохраняю в mypackage / data. Каждый в своем файле с тем же именем для файла и данных в нем (с учетом рекомендаций R для данных в пакете). Каждый набор данных составляет около 10 миллионов, а общая сумма составляет ~ 17 Го. Я не вижу другого пути.
cmbarbu

3
Есть ли причина, по которой вы не использовали paste0?
BroVic 05

33

Мне кажется , что вы могли бы быть лучше со списком , а не использовать orca1, orca2и т.д., ... то это было бы orca[1], orca[2]...

Обычно вы составляете список переменных, различаемых только числом, потому что это число будет удобным способом доступа к ним позже.

orca <- list()
orca[1] <- "Hi"
orca[2] <- 59

В противном случае assignэто именно то, что вам нужно.


11
Я согласен. Обычно, когда люди думают, что хотят на лету давать имена переменным, на самом деле им нужна другая структура данных.
Майкл Данн

9
+1 (FAQ 7.21: cran.r-project.org/doc/FAQ/… ) прекрасно обсуждает это
Бен Болкер,

11

Не создавайте фреймы данных. Сохраните список, назовите его элементы, но не прикрепляйте его.

Самая большая причина этого в том, что если вы создаете переменные на ходу, почти всегда позже вам придется перебирать каждую из них, чтобы выполнить что-то полезное. Здесь вам снова придется перебирать каждое из имен, которые вы создали на лету.

Намного проще назвать элементы списка и перебирать имена.

Что касается attach, это действительно плохая практика программирования в R и может привести к большим проблемам, если вы не будете осторожны.


Итак, сделаем прикрепление, но только после выполнения итерации по списку?
Mox

4

FAQ говорит:

Если у вас есть

varname <- c("a", "b", "d")

ты можешь сделать

get(varname[1]) + 2

для

a + 2

или

assign(varname[1], 2 + 2)

для

a <- 2 + 2

Похоже, вы используете GET, когда хотите оценить формулу, которая использует переменную (например, конкатенацию), и ASSIGN, когда хотите присвоить значение предварительно объявленной переменной.

Синтаксис для assign: assign (x, value)

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

значение: значение, которое будет присвоено x.


0

Еще одно хитрое решение - назвать элементы списка, а attachон:

list_name = list(
    head(iris),
    head(swiss),
    head(airquality)
    )

names(list_name) <- paste("orca", seq_along(list_name), sep="")
attach(list_name)

orca1
#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1          5.1         3.5          1.4         0.2  setosa
# 2          4.9         3.0          1.4         0.2  setosa
# 3          4.7         3.2          1.3         0.2  setosa
# 4          4.6         3.1          1.5         0.2  setosa
# 5          5.0         3.6          1.4         0.2  setosa
# 6          5.4         3.9          1.7         0.4  setosa

14
сложно, но не мудро. если ответ такой, attachчто вы обычно задаете неправильный вопрос ...
Бен Болкер,

-1

А этот вариант?

list_name<-list()
for(i in 1:100){
    paste("orca",i,sep="")->list_name[[i]]
}

Работает отлично. В приведенном вами примере первая строка отсутствует, а затем выдается сообщение об ошибке.


3
Это не касается вопроса OP. У нас есть список фреймов данных, и мы хотим назначить его фреймам данных, названным orca1, orca2 и т. Д.
zx8754

"Список с фреймами данных" = "список фреймов данных"?
Mox
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.