在for循环中生成变量名列表,然后为其分配值


27

我想知道是否有一种简单的方法可以使用for循环生成变量列表并提供其值。

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

在上面的代码中,我尝试创建a1a2a3,其分配到的值1,2,3。但是,R给出一个错误信息。谢谢你的帮助。


3
我怀疑您必须执行此操作-似乎您在以错误的方式进行操作。

@mbq,例如在Eviews中,这是非常正常的编码实践。并不是我在提倡,Eviews在我的顶级恶意软件列表中的评分仅比Excel低一点:)
mpiktas,2011年

6
@mpiktas在R中,创建一个列表,设置其names参数,然后再使用它,attach或者将其转换为带有它list2enveval在其中的环境更为自然。没有循环,解析或其他难看的东西。

@mbq,hm list2env是一个相对较新的功能。当OP想要在顶级环境中获取变量时,它仍然会在某些环境中生成变量。因此,丑陋依然存在:)
mpiktas

2
对于以后类似性质的问题,我建议这类问题实际上属于StackOverflow。这个问题与统计本身无关。
火星

Answers:


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

顺带一提,这就是我爱R的原因。


4
library(fortunes) fortune(106)
RomanLuštrik2011年

@Roman,很奇怪,我parse在阅读R帮助页面后就开始使用。我同意有时这是一个过大的杀伤力,例如在formula管理方面,但是我发现它非常有用。请注意,由于我没有提出问题,因此我无法按照财富中的建议重新考虑该问题。
mpiktas,2011年

1
@mpiktas:这与以下事实有关:在函数中使用基础作用域规则可能导致不可预测的结果。另外(如帮助文件中所述),由于作用域规则不同,R和S可能会给出不同的结果。它也比其他解决方案慢。这在您必须多次执行时很重要。最后但并非最不重要的一点是,在大多数情况下,有一个比使用eval(parse())更优雅,更轻松的解决方案。在这种情况下,可以使用列表或使用assign。
乔里斯·梅斯

1
@mpiktas:我从来没有说过它不足。我只是向您提供了为什么通常由R核心开发团队成员Thomas Lumley建议使用eval(parse())构造的原因。(cfr @ Roman Lustrik的推荐人)
Joris Meys

1
确切地说,不鼓励使用诸如assign来创建多个单元素变量的不良做法
mdsumner,2011年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.