2013-03-25 69 views
2

是否有一種雄辯的方式來使用ddply()來獲得不僅定義最精細的組的輸出,而且還有這些子組的組?plyr與嵌套組?

換句話說,當其中一個分類器是「任何」或「任一」或「無關緊要」。在兩個分組變量的簡單情況下,可以通過單獨調用ddply來完成;然而,當有三個或更多分類器可以設置爲「任何」時,由於必須反覆運行ddply來爲每個新的「任何」+其他組合重複運行ddply,所以這會變得混亂。

重複的例子:

require(plyr) 

## create a data frame with three classification variables 
## and two numeric variables: 
df1=data.frame(classifier1 = LETTERS[sample(2,200,replace=T)], 
classifier2 = letters[sample(3,200,replace=T)], 
classifier3 = rep(c("foo","bar"),100), 
VAR1 = runif(200,50,250), 
VAR2 = rnorm(200,85,20)) 

## apply an arbitrary function to subsets of df1; that is, all unique 
## combinations of the three classifiers. 
dlply(df1, .(classifier1,classifier2,classifier3), 
     function(df) lm(VAR1 ~ VAR2, data=df)) 

$A.a.bar 

Call: 
lm(formula = VAR1 ~ VAR2, data = df) 

Coefficients: 
(Intercept)   VAR2 
    230.5555  -0.8591 


$A.a.foo 

Call: 
lm(formula = VAR1 ~ VAR2, data = df) 

Coefficients: 
(Intercept)   VAR2 
    128.3078  0.3631 

... 

現在,如果我想獲得一些更多的組相同的輸出時,不包括任何/所有分類。例如,如果我想包括當classifier1 =「任何」,我只包括在dlply聲明classifier2和classifier3,像這樣:

dlply(df1, .(classifier2,classifier3), function(df) lm(VAR1 ~ VAR2, data=df)) 

如果我當時就想獲得時classifier2輸出和classifier3 = 「任何」,我會再次從ddply呼叫刪除,只包括classifier1:

dlply(df1, .(classifier1), function(df) lm(VAR1 ~ VAR2, data=df)) 

然而,這變得笨重,當我有更多的分類比3,而各分類可以取出來(即=「任何「) - 組合的數量大幅增加。是否有一種雄辯/快速的方式來獲取我的數據的所有「組羣」輸出?

+0

您可以分別創建組合爲字符串,並直接通過他們沒有'()'使用語法的東西。像'expand.grid'。但我會建議問一個問題關於你的具體問題stats.exchange。我認爲比測試所有情況有更好的確定關係的算法。 – Justin 2013-03-25 01:59:01

+0

賈斯汀 - 我的問題純粹是組織/計算。 lm'函數被包含作爲您或我想要使用的任意函數的佔位符。 – 2013-03-25 15:21:00

回答

4

一種方法是創建組合的列表,然後使用Map創建每個dlply調用的結果列表

您可以結合使用combnlapplydo.call('c',...)創建所有列表1,2,...,n個變量

的組合
xx <- do.call('c',lapply(1:3, function(m) { 
      combn(x=names(df1)[1:3],m, simplify = FALSE)})) 

然後,您可以在通話中使用此Map(這是mapply(..., SIMPLIFY = FALSE)

包裝
results <- Map(f = function(x){dlply(df1,.var=x, .fun = lm, formula = VAR1 ~ VAR2)},xx) 

或者你可以只通過一個函數來combn - 這將做同樣的事情

results <- do.call('c',lapply(1:3, function(m) { 
    combn(x=names(df1)[1:3],m, simplify = FALSE, 
     function(vv) {dlply(df1,.var=vv, .fun = lm, formula = VAR1~VAR2)}) 
    })) 
+0

這真是太棒了 - 謝謝!另外,我想調用'results'像這樣:'results [[「A.c.bar」]]',但是列表結構阻止了這個。我可以完成這樣的解決方法:'for(我在1:長度(結果))results2 = c(r3,results [[i]])'但是有沒有更高效的方法? – 2013-03-25 15:17:49