2012-08-04 104 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