2010-09-14 1 views
1

Я ищу назначение объектов в цикле. Я читал, что какая-то форма eval(parse( - это то, что мне нужно для выполнения этого, но я сталкиваюсь ошибки листинга invalid text или no such file or directory. Ниже приведен пример кода, в общем, то, что я пытаюсь сделать:Назначение и удаление объектов в цикле: eval (parse (paste (

x <- array(seq(1,18,by=1),dim=c(3,2,3)) 
for (i in 1:length(x[1,1,])) { 
    eval(parse(paste(letters[i],"<-mean(x[,,",i,"])",sep="") 
} 

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

for (i in 1:length(x[1,1,])) eval(parse(paste("rm(",letters[i],")",sep=""))) 

Оба eval(parse(paste( частей этого скрипта возвращают ошибки для invalid text или no such file or directory. Я что-то упустил в использовании eval(parse(? Есть ли более простой/лучший способ назначения объектов в цикле?

ответ

9

Это довольно отвратительным и разочаровывающим способом. Используйте команду assign для назначения аргумента и аргумента rm для удаления объектов.

> for (i in 1:length(x[1,1,])) { 
+ assign(letters[i],mean(x[,,i])) 
+ } 
> ls() 
[1] "a" "b" "c" "i" "x" 
> a 
[1] 3.5 
> b 
[1] 9.5 
> c 
[1] 15.5 
> for (i in 1:length(x[1,1,])) { 
+ rm(list=letters[i]) 
+ } 
> ls() 
[1] "i" "x" 
> 

Всякий раз, когда вы чувствуете необходимость использовать parse, помните состояние (106):

Если ответ разобрать() вы должны обычно пересмотреть вопрос.
- Томас Ламли, R-помощь (февраль 2005)

+7

Я добавляю «создателя отвратительного и расстраивающего кода» в своей биографии. –

+1

Я добавлю это в свою биографию. –

4

Очень плохая идея; вы никогда не должны использовать eval или parse в R, если вы не знаете, что делаете.
Переменные могут быть созданы с помощью:

name<-"x" 
assign(name,3) #Eqiv to x<-3 

и удалены:

name<-"x" 
rm(list=name) 

Но в вашем случае, это может быть сделано с простым именем вектора:

apply(x,3,mean)->v;names(v)<-letters[1:length(v)] 
v 
v["b"] 
#Some operations on v 
rm(v) 
+0

Er, гм ... никогда не используя 'Eval '- хорошая идея на некоторых языках, но вычисление на языке является одной из сильных сторон R ... http://stat.ethz.ch/R-manual/R-devel/doc/manual/R-lang.html# Computing-on-language. Но да, в этом контексте предпочтительным является назначение. – Vince

+1

@Vince Это было в некотором смысле никогда не использовать 'eval', пока вы не продвинулись ;-) – mbq

+3

fortune (106):« Если ответ разобран (), вы должны, как правило, переосмыслить вопрос ». Томас Ламли, R-help (февраль 2005) –

5

Лучше всего, чтобы избежать использования либо Eval (паста (или назначить в данном случае Doing либо создает много глобальных переменных, которые просто вызывают дополнительные головные боли позже. .

Наилучший подход является использование существующих структур данных для хранения объектов, списки наиболее общие для этих типов случаев.

Затем вы можете использовать [л.с.] применять функции, чтобы делать вещи с разными элементы, как правило, намного быстрее, чем переходы по глобальным переменным.Если вы хотите сохранить все созданные объекты, у вас есть только один список для сохранения/загрузки. Когда пришло время их удалить, вы просто удаляете один единственный объект, и все прошло (без циклов). Вы можете назвать элементы списка, чтобы ссылаться на них по имени позже или по индексу.

+0

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

8

Хотя, кажется, есть более эффективные способы справиться с этим, если вы действительно сделали хотите использовать «Eval (синтаксический разбор (вставку (» подход, что теряешь текст флаг.

синтаксический анализ предполагает, что его первым аргументом является путь к файлу, который он будет разбирать.В вашем случае вы не хотите, чтобы он читал файл для синтаксического анализа, вы хотите передать ему некоторый текст для разбора. Таким образом, ваш код, переписан (в том, что было названо отвратительное формой выше) будет

letters=c('a','b','c') 
x <- array(seq(1,18,by=1),dim=c(3,2,3)) 
for (i in 1:length(x[1,1,])) { 
    eval(parse(text=paste(letters[i],"<-mean(x[,,",i,"])",sep=""))) 
} 

В дополнение к не указав «текст =» вы пропустили несколько круглых скобок на правой стороне, чтобы закрыть разобрана и eval.

Похоже, ваша проблема была решена, но для людей, которые достигают эту страницу, которые действительно хотят использовать Eval (синтаксический разбор (паста, я хотел бы уточнить.