Створіть список імен змінних у циклі for, а потім призначте їм значення


27

Цікаво, чи існує простий спосіб скласти список змінних, використовуючи цикл for, і надати його значення.

for(i in 1:3)
{
  noquote(paste("a",i,sep=""))=i
}

У наведеній вище коді, я намагаюся створити a1, a2, a3, що задають значення 1, 2, 3. Однак, R видає повідомлення про помилку. Спасибі за вашу допомогу.


3
Я сумніваюся, що ви повинні це зробити - здається, ви робите щось дуже неправильно.

@mbq, наприклад, в Eviews це досить нормальна практика кодування. Не те, що я за це виступаю, Eviews оцінює лише трохи нижче, ніж Excel, у моєму найкращому списку злого програмного забезпечення :)
mpiktas

6
@mpiktas У R, більш природно скласти список, встановити його namesпараметр і пізніше або просто використовувати його, attachабо перетворити його в середовище з list2envі evalвсередині нього. Без петель, розбору та інших потворних речей.

@mbq, hm, list2envє відносно новою функцією. І все-таки він створюватиме змінні в деякому середовищі, коли ОП хоче отримати змінні у верхньому середовищі. Тож потворність все ще залишається :)
mpiktas

2
Для майбутніх питань подібного характеру я б припустив, що подібне питання насправді належить до StackOverflow. Питання не має нічого спільного зі статистикою.
Марс

Відповіді:


41

Ви шукаєте assign().

for(i in 1:3){
  assign(paste("a", i, sep = ""), i)    
}

дає

> ls()
[1] "a1"          "a2"          "a3" 

і

> a1
[1] 1
> a2
[1] 2
> a3
[1] 3

Оновлення

Я погоджуюся, що використання циклів - це дуже часто поганий стиль кодування R (див. Обговорення вище). Використовуючи list2env()(дякую @mbq, що згадував про це), це ще одне рішення питання @Han Lin Shang:

x <- as.list(rnorm(10000))
names(x) <- paste("a", 1:length(x), sep = "")
list2env(x , envir = .GlobalEnv)

21

Якщо значення векторні, цикл не потрібен:

vals <- rnorm(3)
n    <- length(vals)
lhs  <- paste("a",    1:n,     sep="")
rhs  <- paste("vals[",1:n,"]", sep="")
eq   <- paste(paste(lhs, rhs, sep="<-"), collapse=";")
eval(parse(text=eq))

Як бічна примітка, це причина, чому я люблю Р.


4
library(fortunes) fortune(106)
Роман Луштрик

@ Роман, дивно, я почав користуватися, parseпрочитавши довідкові сторінки R. Я погоджуюся, що іноді це надмірність, наприклад, в formulaуправлінні, але я вважаю це дуже корисним. Зауважте, що я не можу переосмислити питання, як було запропоновано у фортуні, оскільки я його не задавав.
mpiktas

1
@mpiktas: це пов'язано з тим, що основні правила розміщення можуть призвести до непередбачуваних результатів при використанні в межах функції. Також (як зазначено у довідкових файлах), R і S можуть дати різний результат через різницю в правилах визначення обсягу. Це також повільніше, ніж інші рішення. Це буде мати значення, коли вам доведеться це робити багато разів. І останнє, але не менш важливе, в більшості випадків є більш елегантне і простіше рішення, ніж використання eval (parse ()). У цьому випадку це робота зі списками або використання призначень.
Йоріс Майс

1
@mpiktas: Я ніколи не казав, що це недостатньо. Я щойно дав вам причину, чому взагалі не рекомендується конструкція eval (parse ()), наприклад, Томас Лумлі, член команди основної команди R. (пор. згадка @ Романа Лустрика)
Йоріс Мейс

1
саме така погана практика, як використання присвоєння для створення декількох змінних одного елемента, повинна бути
обережно
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.