2013-04-11 81 views
-1

我:將字符向量轉換爲R中的數值向量以賦值?

z = data.frame(x1=a, x2=b, x3=c, etc) 

我試圖做的事:

for (i in 1:10) 
{ 
    paste(c('N'),i,sep="") -> paste(c('z$x'),i,sep="") 
} 

問題:

  1. paste(c('z$x'),i,sep="")產量"z$x1", "z$x1",而不是調用的實際值。我需要評估表達。我試過as.numeric, eval。似乎都沒有工作。

  2. paste(c('N'),i,sep="")收益率"N1", "N2"。我需要這個表達僅僅作爲名字。如果我嘗試給它賦值如paste(c('N'),5,sep="") -> 5,即"N5" -> 5而不是N5 -> 5,那麼我將賦值的目標擴展到非語言對象。

這個任務是很簡單,因爲我可以簡單地做:

N1 = X1 ... N2 = X2 ...

等,但我想學習新的東西

+1

使用'get'和'assign',但不這樣做 - 使用列表來代替。有關於此的R常見問題解答以及許多SO問題(現在您知道正確的事情要尋找)。 – 2013-04-11 21:20:01

回答

2

我建議使用類似for(i in 1:10) z[,i] <- N[,i] ...

但是,既然你說你想學習新的東西,你可以玩弄parsesubstitute

注意:這些小工具很有趣,但有經驗的用戶(不是我)避免它們。

這被稱爲「在語言上計算」。這非常有趣,它有助於理解R的工作方式。讓我試着給出一個簡介:

基本的語言結構是一個常數,就像數字或字符向量一樣。這是微不足道的,因爲它與「未評估」版本沒有區別,但它是更復雜表達式的基石之一。

(正式)基本語言對象是symbol,也被稱爲name。它只不過是一個指向另一個對象的指針,也就是標識另一個可能存在也可能不存在的對象的標記。例如,如果您運行的是x <- 10,則x是一個符號,指的是值10。換句話說,評估符號x會得到數字矢量10。評估不存在的符號會產生錯誤。

符號看起來像一個字符串,但它不是。您可以使用as.symbol("x")將字符串變成符號。

下一個語言對象是call。這是一個遞歸對象,實現爲list,其元素是常量,符號或其他調用。第一個元素必須是而不是是一個常數,因爲它必須評估爲真正的function將被調用。其他元素是這個函數的參數。

如果第一個參數不計算爲現有函數,則R將拋出Error: attempt to apply non-functionError: could not find function "x"(如果第一個參數是未定義的符號或指向函數以外的其他函數)。

實施例:碼字行f(x, y+z, 2)將被解析爲4個元素的列表,第一個是f(作爲標誌),第二個是x(另一符號),第三另一call和第四數字常數。第三個元素y+z只是一個帶有兩個參數的函數,因此它解析爲三個名稱的列表:'+',yz

最後,還有expression對象,即調用/符號/常量列表,這些對象將被逐個評估。

您會在這裏找到大量的信息:

https://github.com/hadley/devtools/wiki/Computing-on-the-language

好了,現在讓我們回到你的問題:-)

什麼你都試過不行,因爲paste輸出是一個字符串,賦值函數將其作爲第一個參數作爲結果賦予符號,以創建或修改。或者,第一個參數也可以評估爲與替代函數關聯的呼叫。這些有點棘手,但它們是由賦值函數本身處理的,而不是由解析器處理的。

您看到的錯誤消息target of assignment expands to non-language object由分配函數觸發,這正是因爲您的目標計算結果爲字符串。

我們可以解決這個問題,在正確的地方建立一個具有所需符號的呼叫。最「暴力」的方法是把所有的字符串,並使用解析裏面:

parse(text=paste('N',i," -> ",'z$x',i,sep="")) 

另一種方式來獲得有使用substitute

substitute(x -> y, list(x=as.symbol(paste("N",i,sep="")), y=substitute(z$w, list(w=paste("x",i,sep=""))))) 

內替代創建call小號z$x1z$x2等。外部替代品將此調用作爲賦值的目標,並將符號N1,N2等作爲值。

parse導致expressionsubstitutecall中。兩者都可以傳遞給eval以獲得相同的結果。

只是最後一個音符:我再說一遍,這一切的目的是作爲一個說教例如,爲了幫助理解語言的內部運作,但它是從良好的編程習慣使用parsesubstitute,除非有真的是別無選擇。

1

我不完全確定你要完成什麼。但是,這裏有一個猜測:

### Create a data.frame using the alphabet 
data <- data.frame(x = 'a', y = 'b', z = 'c') 

### Create a numerical index corresponding to the letter position in the alphabet 
index <- which(tolower(letters[1:26]) == data[1, ]) 

### Use an 'lapply' to apply a function to every element in 'index'; creates a list 
val <- lapply(index, function(x) { 
    paste('N', x, sep = '') 
}) 

### Assign names to our list 
names(val) <- names(data) 

### Observe the result 
val$x 
2

A data.framenamed list。通常好的做法,地道R-ish不是有很多在全球環境中的對象,但已經與(或類似)中列出的對象和使用lapply

你可以使用list2env到multiassign的命名元素您的列表(data.frame中的列)到全球環境

DD <- data.frame(x = 1:3, y = letters[1:3], z = 3:1) 
list2env(DD, envir = parent.frame()) 
## <environment: R_GlobalEnv> 
## ta da, x, y and z now exist within the global environment 
x 
## [1] 1 2 3 
y 
## [1] a b c 
## Levels: a b c 
z 
## [1] 3 2 1