2012-08-04 72 views
-1

如何选择动态命名变量的第二列?从动态变量中选择一列

我创建了“population.USA”,“population.Mexico”,“population.Canada”形式的变量。每个变量都有一年的列和另一列的人口值。我想在循环过程中从这些变量中选择第二列。

我用这个语法:

sprintf("population.%s", country)[, 2] 

[R返回错误:Error in sprintf("population.%s", country)[, 2] : incorrect number of dimensions

+1

请参阅加文的答案,但您可以通过查看'sprintf('population。%s',country)'返回的内容来告诉您的示例不会工作。 – Justin 2012-08-04 21:37:33

+0

我仍然在学习如何解释R的输出。我没有意识到输出结果告诉我这是一个字符串。也许它只是将变量名显示为一个字符串?或者,即使它确实返回了一个字符串,我也习惯了语言(PHP),这足以获得该值。 – 2012-08-04 22:38:45

回答

6

?get。下面是一个示例:

> country <- "FOO" 
> assign(sprintf("population.%s", country), data.frame(runif(5), runif(5))) 
> 
> get(sprintf("population.%s", country))[,2] 
[1] 0.2241105 0.5640709 0.5945869 0.1830719 0.1895938 

如果出现错误,查看由函数返回的对象是非常重要的。它是立即清楚为什么你的例子,如果你只是看看它返回失败:

> sprintf("population.%s", country) 
[1] "population.FOO" 

在这一点上它会立即清除,如果你还不知道或者想到读?sprintf,即sprintf()回报一个字符串不是该名称的对象。有了这些知识,你就可以将问题缩小到如何从计算出的名字中回想一个对象?

+0

谢谢加文,我没有意识到R不会搜索一个等于字符串的对象。 – 2012-08-04 22:39:30

+0

@DonnyP如果R总是决定,如果一个字符串包含一个对象的名称,它将返回该对象,这将是可怕的。 – Dason 2012-08-05 00:35:21

11

根据您的在最后几分钟的问题顺序,我给你两个一般性建议,您熟悉R:

  1. 不要使用sprintf。请使用assign

现在,显然,这些功能有时是有用的。但是在你掌握了关于R的数据结构的一些基本知识之前,你已经了解了它们太早了。尝试编写没有拐杖的代码(暂时!),因为它们只会导致你的问题。

与其为每个国家的人口创建单独的变量,将它们放在一个列表中。

population <- vector("list",3) 
names(population) <- c('USA','Mexico','Russia') 

然后你可以使用每个每个国家的名字字符串表示访问:

population[['USA']] <- 10000 

或者,

region <- 'USA' 
population[[region]] 

在这个例子中,我分配了一个单值到列表元素,列表将包含任何其他数据类型,包括矩阵或数据框。与使用sprintfassign相比,它将会减少很多,并且更安全和更高效。

+0

感谢今天的所有帮助Joran - 我很清楚,我错过了在R中构建和使用数据集的基础知识。你是否知道一个用于学习这些知识的好资源?我经历了许多'教程'和介绍在R中使用R和时间序列,但不幸的是,他们似乎并没有教会基础知识,让我们像使用其他语言一样灵活地使用它。 – 2012-08-04 22:34:16

+0

关于sprintf的使用,我不知道在使用循环时传递值的任何替代方法。 – 2012-08-04 22:36:27

+0

@DonnyP另一种方法是不将值传入循环(或“粘贴”)!而是使用诸如命名列表和R的列表函数之类的东西。像'[','[['和'apply'家族。 – Justin 2012-08-04 22:44:16