2011-05-19 43 views
6

我很努力去理解這是行不通的。如何在功能內使用/內部使用?

df <- data.frame(a=1:10, b=1:10) 

foo <- function(obj, col) { 
    with(obj, ls()) 
    with(obj, print(col)) 
} 
foo(df, a) 

[1]的 「a」 「b」 的

錯誤打印(COL):對象 'A' 未找到

如果這樣沒有問題:

with(df, print(a)) 
+1

這可能會有助於更廣泛地瞭解您正在嘗試完成的內容。 – 2011-05-19 15:22:48

回答

12

with更得心應手,在提高可讀性交互式上下文,但可能會在編程環境中傷害大腦,在這種編程環境中,來回傳遞函數並處理不同環境中的事物。一般來說,在R中,使用符號而不是名稱是一種「語義糖」,在交互式使用中方便且可讀,但對編程適度不贊成[例如$,subset])。如果你願意,只要使用一個名稱("a")妥協,而不是一個符號(a),那麼我會建議回落至簡單obj[[col]],而不是在這裏使用with ...

所以,作爲一個自-contained答案:

foo <- function(object,col) { 
    print(names(object)) 
    print(object[[col]]) 
} 

如果你想允許多個列(即特徵向量)

foo <- function(object,col) { 
    print(names(object)) 
    print(object[col]) 
} 

編輯:refra從使用subset的功能,在@哈德利的建議

(這將打印答案作爲數據框,即使選擇了單個列,這可能不是你想要的)。

+0

刪除了我的回答,因此您可能需要更改引薦。併爲警告+1。 – 2011-05-19 15:49:02

+0

感謝您的所有答案。我並不是真的想要打印任何東西,我只是希望能夠將該列傳遞給其他功能。看看像列的變量名稱,而不是字符串的函數,我認爲這很容易做到這一點。我想我會堅持傳遞字符串。 :) – rafalotufo 2011-05-20 02:01:30

+0

除了在函數內部使用子集是不好的形式,因爲如果列不如您期望的那樣您會得到令人困惑的錯誤消息 - 最好使用直接子集。 – hadley 2011-05-22 17:08:36

4

任何傳遞給函數的東西都必須是一個對象,一個字符串或一個數字。這裏有兩個問題:

  1. 在這種情況下,你試圖傳遞「a」作爲對象,當你真的應該像一個字符串傳遞它。
  2. with(obj,ls()))將返回到函數環境(函數範圍),而不是屏幕,除非您讓它打印。

你想要的是更象:

foo <- function(obj, col) { 
     print(with(obj, ls())) 
     with(obj, print(obj[[col]])) 
    } 

foo(df, "a") 

或者,如果你只是尋找一個欄要打印:

foo <- function(obj, col) { 
      with(obj, print(obj[[col]])) 
     } 

foo(df, "a") 
+0

但這並不是他想要的:他想要打印df $ a。 – 2011-05-19 15:24:03

+0

目前尚不清楚他想印什麼。對我來說,看起來他想要打印兩行。一個具有obj的colname,另一個具有指定列的內容。 – 2011-05-19 15:29:03

1

在函數中,參數col在函數中使用之前被評估(與交互式使用相反)。在這裏你有兩個解決這個問題的方法。

foo1 <- function(obj, col) { 
      with(obj, print(eval(col))) 
     } 
foo1(mydf, quote(a))# here you have to remember to quote argument 


foo2 <- function(obj, col) { 
      col <- as.expression(as.name(substitute(col)))#corrected after DWIN comment 
      with(obj, print(eval(col))) 
     } 
foo2(mydf, a)# this function does all necessary stuff 
+0

+1用於回答提出的問題,雖然我仍然認爲與/ eval /等混亂。用這種方法是一個壞主意...... – 2011-05-19 21:09:23

+0

我無法讓第二個人工作。通常當你使用'eval'時,你需要指定一個環境。 – 2011-05-20 04:13:59