2013-10-31 48 views
0

我需要將一系列操作應用於data.frame中的不同變量。爲了使我的代碼更短,更容易閱讀,我試圖使這些操作功能化。但是,我在使用變量(在函數中)引用data.frame中的變量時遇到了問題。這裏是一個玩具例子:在函數中使用變量來引用數據中的變量。框架

set.seed(1) 
dframe <- data.frame(ID=rep(1:4, each=3), 
        cond=rep(c("a", "b"), each=6), 
        x=rnorm(12)) 
dframe 
    ID cond   x 
1 1 a -0.6264538 
2 1 a 0.1836433 
3 1 a -0.8356286 
4 2 a 1.5952808 
5 2 a 0.3295078 
6 2 a -0.8204684 
7 3 b 0.4874291 
8 3 b 0.7383247 
9 3 b 0.5757814 
10 4 b -0.3053884 
11 4 b 1.5117812 
12 4 b 0.3898432 

get.means <- function(var, dframe){ 
    dframe <- dframe[order(dframe$ID),] 
    mat <- aggregate(var~ID, data=dframe, FUN=mean) 
    mat 
} 
get.means(var=x, dframe=dframe) 
Error in eval(expr, envir, enclos) : object 'x' not found 

我可以得到它通過使用get.means(var=dframe$x, dframe=dframe)工作,但這會導致其他問題的道路。以下是我已經嘗試了一些其他的東西,都沒有奏效:

get.means2 <- function(var, dframe){ 
    dframe <- dframe[order(dframe$ID),] 
    mat <- aggregate(get(var)~ID, data=dframe, FUN=mean) 
    mat 
} 
get.means2(var=x, dframe=dframe) 
Error in get(var) : object 'x' not found 

get.means3 <- function(var, dframe){ 
    dframe <- dframe[order(dframe$ID),] 
    mat <- aggregate(eval(var)~ID, data=dframe, FUN=mean) 
    mat 
} 
get.means3(var=x, dframe=dframe) 
Error in eval(var) : object 'x' not found 

get.means4 <- function(var, dframe){ 
    dframe <- dframe[order(dframe$ID),] 
    mat <- aggregate(dframe[,var]~ID, data=dframe, FUN=mean) 
    mat 
} 
get.means4(var=x, dframe=dframe) 
Error in `[.data.frame`(dframe, , var) : object 'x' not found 

回答

2

x僅被定義在dframe範圍。你可以試試這個:

get.means4(var='x', dframe=dframe) 

或以這種方式甚至get.means3(雖然我不建議):

get.means3(var=dframe$x, dframe=dframe) 

get.means <- function(var, dframe){ 
    aggregate(as.formula(paste(var, '~ ID')), data=dframe, FUN=mean) 
} 

get.means(var='x', dframe=dframe) 

您還可以使用列名調用get.means4

在最後一種情況下,您可以安全刪除eval並離開:

aggregate(var~ID, data=dframe, FUN=mean) 
+0

感謝您的幫助。範圍正在殺死我。我只是再次閱讀手冊,我一定錯過了一些東西。 #3工程與我的玩具的例子,但進一步瓦特/實際(即更復雜)的代碼。解決方法(1)版本似乎最好,但開發人員認爲人們應該如何做到這一點?看起來很尷尬。 – gung

+0

一般來說,如果使用'$'語法,最好避免使用'data'參數。雖然有些函數可以像這樣調用:「foobar(df $ foo〜bar,data = df)」,它可以給你帶來意想不到的結果。在這種情況下,使用'foobar(df $ foo〜df $ bar)',否則'df $ bar'可以解釋爲'df $ df $ bar'。就我個人而言,我認爲使用字符串名稱是最好的解決方案,並應該與數據框和矩陣一起工作。 – zero323

1

您可以考慮使用data.table而不是data.frame。它允許更小,也許更易於管理的代碼。

require(data.table) 
DT <- data.table(ID = rep(1:4, each = 3), cond = rep(c("a", "b"), each = 6), x = rnorm(12)) 
DT 
##  ID cond   x 
## 1: 1 a -0.97191681 
## 2: 1 a 1.28097125 
## 3: 1 a -0.47717701 
## 4: 2 a -0.29965951 
## 5: 2 a 1.06189839 
## 6: 2 a 1.09880286 
## 7: 3 b -1.46961507 
## 8: 3 b 1.12854103 
## 9: 3 b -0.09556682 
## 10: 4 b 0.45225307 
## 11: 4 b -0.64993127 
## 12: 4 b -0.59079915 

DT[, mean(x), by = ID] 
## ID   V1 
## 1: 1 -0.28531921 
## 2: 2 0.01713826 
## 3: 3 0.23810745 
## 4: 4 -0.16118247 
+0

謝謝。我真的不知道'data.table',並且假設這只是我需要解決的更復雜代碼的一小部分的一個玩具示例,我應該真正留在w/base R.我打算試圖去學習它 - 這些小插曲看起來很有幫助。 – gung