2011-05-29 52 views
1

我想基於給定變量的邊界值分割數據幀,計算邊界兩側的某些內容並輸出矩陣(最好是數據幀)。示例代碼波紋管:在連續變量邊界處分割數據幀並在兩邊執行計算

set.seed(1) 
tdata <- data.frame(a1=rnorm(100, mean=5, sd=2), a2=rep(0:1, length.out=100)) 
tall <- sapply(1:9, function(x) { 
    d <- split(tdata, tdata$a1 <= x) 
    sapply(d, function (y) { 
    1 - max(table(y$a2)/nrow(y)) 
    }) 
}) 

我的結果:

> allErr 
      [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7] 
FALSE 0.4949495 0.4895833 0.4943820 0.4933333 0.4444444 0.4411765 0.3333333 
TRUE 0.0000000 0.2500000 0.4545455 0.4800000 0.4347826 0.4696970 0.4705882 
     [,8] [,9] 
FALSE 0.5 0.5 
TRUE 0.5 0.5 

我的連續變量是tdata$a1,我想每次使用的邊界值從1:9分割數據幀中2,上a2執行計算對於拆分的每個部分,並將其返回。

我的問題在這裏:什麼是最好的方式來做到這一點在優雅(看着plyr解決方案,但不能避免使用第一sapply),更重要的是正確使用其他R功能,我可能不知道的。我也擔心我的解決方案不會比我目前擁有的(〜10000行)大得多的數據幀進行擴展。

回答

3

沒有更多優雅是雨後春筍般在腦海中,但這種修改可能會幫助您解決方案規模略勝一籌通過分割索引向量,而不是整個數據幀:

set.seed(1) 
tdata <- data.frame(a1=rnorm(100, mean=5, sd=2), a2=rep(0:1, length.out=100)) 
tall <- sapply(1:9, function(x) { 
     d <- split(seq_along(tdata$a2), tdata$a1 <= x) 
     sapply(d, function (y) { 
      1 - max(table(tdata$a2[y])/length(y)) 
     }) 
     }) 

這個玩具例中的性能增益相當小,很可能是因爲你的數據框只有兩列。如果您的真實數據框包含更多列,您將看到拆分索引向量帶來的更多益處。

+0

+1該指數矢量 – diliop 2011-05-29 21:48:13

1

而且不知道優雅,但打出來的內部函數作爲fun0a和「分裂-lapply」圖案作爲tsplit,然後整個迭代是

fun0a <- function(x, ...) 
    1 - max(table(x)/length(x)) 
tsplit <- function(thresh, x, splt, fun, ...) 
    lapply(split(x, splt <= thresh), fun, ...) 
sapply(1:9, tsplit, data$a2, tdata$a1, fun0a) 

這使用的sapplylapply代替並直接分割單列數據,而不是通過索引或整個數據框。 tsplit和外sapply獲取將在類似的情況下,再使用例如,母雞內函數實際上取決於在數據幀上,通過索引(計算一次,在外sapply)的值而無需

fun0b <- function(i, df, ...) 
    1 - max(table(df[i,"a2"])/length(i)) 
with(tdata, 
    sapply(1:9, tsplit, seq_along(a1), a1, fun0b, tdata)) 

tsplittapply所以可以實現爲

tsplit <- function(thresh, x, splt, fun, ...) 
    tapply(x, splt <= thresh, fun, ...) 
+0

我想這裏的高貴是瞄向一個plyr實現不依賴於外部sapply但ddply內做的一切。 – diliop 2011-05-30 02:21:10