将元素名称引用到其他元素

时间:2015-01-20 10:13:17

标签: r

我在R中遇到问题,它是以下内容: 如何为元素赋值,然后再调用一个元素,以你的名字引用之前定义的元素。

因此,您定义了一个元素x

i <- value

稍后您使用x.i,其中“i”应为其值。

在以下两种情况下,这是一个问题:

1) 首先,创建10个名为x.1至x.10

的元素
for(i in 1:10){
        assign(paste0("X.", i), 1:3)
}

然后你想要改变x.1中的元素名称直到x.10

for(i in 1:10){
        assign(names(paste0("X.", i)), c("foo","bar","norf"))
}

这不起作用。

2) 我想定义两个值:

year <- 1
code <- 2

然后在数据帧“Data.year”(=“Data.1”)中,只应存储列“代码”等于先前定义的“代码”(= 2)的值的那些观察值。使用名称格式:“Data.year.code”(= Data.1.2)

assign(paste0("Data.", i, code, sep="."), as.name(paste("Data",year , sep="."))[as.name(paste("Data",y , sep="."))$code==code,])

这里我尝试使用as.name函数,但这不起作用。 问题是R显然无法重新确认表达式“Data.year.code”中的“year”和“code”具有值。在stata中你通过使用`来解决这个问题,但我现在不知道如何在R中这样做。 通常情况下,当我不知道答案时,我只是谷歌。但我不知道我应该如何命名这个问题因此无法找到它......

它应该有一个简单直接的解决方案。

2 个答案:

答案 0 :(得分:1)

根据您使用assign的代码,选项是(但正如@Roland在评论中提到的那样,使用&#34;列表&#34;会更容易,更安全。)

for(i in 1:10){
 assign(paste0('X.',i), `names<-`(get(paste0('X.', i)), 
        c('foo', 'bar', 'norf')))
 }

X.1
#foo  bar norf 
#  1    2    3 
X.2
# foo  bar norf 
#  1    2    3 

或者您可以在列表中试用

 lst <- lapply(mget(paste0('X.',1:10)), function(x) {
                names(x) <- c('foo', 'bar', 'norf')
              x})

如果您需要更改原始变量以反映更改

 list2env(lst, envir=.GlobalEnv)

更新

如果您需要更改矢量中的值,则更容易

 list2env(lapply(mget(paste0('X.', 1:10)), 
   function(x) x <- c('foo', 'bar', 'norf')), envir=.GlobalEnv)

 X.1
#[1] "foo"  "bar"  "norf"

或者只是

 for(i in 1:10){
   assign(paste0('X.', i), c('foo', 'bar', 'norf'))
  }

答案 1 :(得分:0)

这个想法(尽管我需要告诉你,R社区有点不满)是制作一个“大”的想法。循环中的字符串,将在之后进行评估:

这就像你说的那样有效:

 for(i in 1:10){
  assign(paste0("X.", i), 1:3)
}

所以为了更改名称,请执行以下操作:

for(i in 1:10){
   eval(parse(text=sprintf('X.%s <- c("foo","bar","norf")',i)))
}

输出:

> X.1
[1] "foo"  "bar"  "norf"
> X.2
[1] "foo"  "bar"  "norf"

所以你在这个场合用sprintf制作一个大字符串:

> cat(sprintf('X.%s <- c("foo","bar","norf")',i)) #cat is used for demonstration here
X.1 <- c("foo","bar","norf") #this is the string for i==1 for example

然后将其转换为parse的表达式,然后使用eval评估表达式。

正如我先前所说,它不是最好的技术,但说实话,它已经帮助了我很多次。