Produza uma lista de nomes de variáveis ​​em um loop for e atribua valores a elas


27

Gostaria de saber se existe uma maneira simples de produzir uma lista de variáveis ​​usando um loop for e fornecer seu valor.

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

No código acima, eu tento criar a1, a2, a3, que atribuem aos valores de 1, 2, 3. No entanto, R dá uma mensagem de erro. Obrigado pela ajuda.


3
Duvido que você precise fazer isso - parece que você está criando algo de uma maneira muito errada.

@mbq, no Eviews, por exemplo, essa é uma prática bastante normal de codificação. Não que eu estou defendendo isso, as taxas de EViews apenas uma pouco menor do Excel na minha lista de software mal top :)
mpiktas

6
@mpiktas No R, é mais natural fazer uma lista, definir seu namesparâmetro e depois apenas usá- attachlo ou convertê-lo em um ambiente com list2enve evaldentro dele. Sem loops, análise ou outras coisas feias.

@mbq, hm, list2envé uma função relativamente nova. E ainda assim produzirá as variáveis ​​em alguns ambientes, quando o OP quiser obter as variáveis ​​no ambiente superior. Portanto, a feiúra ainda permanece :)
mpiktas 16/05

2
Para perguntas futuras de natureza semelhante, sugiro que esse tipo de pergunta realmente pertença ao StackOverflow. A questão não tem nada a ver com estatísticas em si.
Marte

Respostas:


41

Você está procurando assign().

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

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

e

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

Atualizar

Concordo que o uso de loops é (com muita frequência) um estilo ruim de codificação R (consulte a discussão acima). Usando list2env()(obrigado a @mbq por mencioná-lo), esta é outra solução para a pergunta de Han Lin Shang:

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

21

Se os valores estiverem em vetor, o loop não será necessário:

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

Como uma observação lateral, esta é a razão pela qual eu amo R.


4
library(fortunes) fortune(106)
Roman Luštrik 16/05

@ Roman, estranho, comecei a usar parsedepois de ler as páginas de ajuda do R. Concordo que às vezes é um exagero, por exemplo, na formulaadministração, mas achei muito útil. Note que não posso repensar a questão, como sugerido na fortuna, pois não a fiz.
mpiktas 16/05

11
@mpiktas: tem a ver com o fato de que as regras de escopo subjacentes podem resultar em resultados imprevisíveis quando usadas em uma função. Além disso (conforme mencionado nos arquivos de ajuda), R e S podem fornecer um resultado diferente devido à diferença nas regras de escopo. Também é mais lento que outras soluções. Isso será importante quando você precisar fazer isso várias vezes. E por último mas não menos importante, na maioria dos casos, há uma solução mais elegante e mais fácil do que usar eval (parse ()). Nesse caso, está trabalhando com listas ou usando o assign.
Joris Meys

11
@mpiktas: Eu nunca disse que é deficiente. Eu apenas expliquei o motivo pelo qual, em geral, uma construção eval (parse ()) é desaconselhada, por exemplo, por Thomas Lumley, membro da equipe de desenvolvimento do núcleo R. (cfr o refernce de @Roman Lustrik)
Joris Meys

11
exatamente, más práticas como o uso de atribuir para criar múltiplas variáveis de um único elemento deve ser desencorajado
mdsumner
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.