2011-08-30 62 views
2

我正在使用聚合命令對R中的數據進行挑戰分組。我可以用SQL比較容易地做到這一點,但是我不能和R一樣獲得同樣的效果。作爲一個例子,下面是一組測試數據,它提供了我正在尋找的東西的本質:R中的數據分組(類似於使用SQL中的WHERE子句求和)

create table #data(v1 varchar(4), v2 int, v3 int, v4 int,v5 int) 
insert #data(v1, v2, v3, v4, v5) values(8000, 3, 8, 7, 11) 
insert #data(v1, v2, v3, v4, v5) values(8001, 4, 9, 8, 12) 
insert #data(v1, v2, v3, v4, v5) values(8002, 5, 10, 9, 13) 
insert #data(v1, v2, v3, v4, v5) values(8003, 6, 11, 7, 14) 
insert #data(v1, v2, v3, v4, v5) values(8000, 7, 12, 8, 11) 
insert #data(v1, v2, v3, v4, v5) values(8001, 3, 13, 9, 12) 
insert #data(v1, v2, v3, v4, v5) values(8002, 4, 14, 7, 13) 
insert #data(v1, v2, v3, v4, v5) values(8003, 5, 8, 8, 14) 
insert #data(v1, v2, v3, v4, v5) values(8000, 6, 9, 9, 11) 
insert #data(v1, v2, v3, v4, v5) values(8001, 7, 10, 7, 12) 
insert #data(v1, v2, v3, v4, v5) values(8002, 3, 11, 8, 13) 
insert #data(v1, v2, v3, v4, v5) values(8003, 4, 12, 9, 14) 
insert #data(v1, v2, v3, v4, v5) values(8000, 5, 13, 7, 11) 
insert #data(v1, v2, v3, v4, v5) values(8001, 6, 14, 8, 12) 
insert #data(v1, v2, v3, v4, v5) values(8002, 7, 8, 9, 13) 
insert #data(v1, v2, v3, v4, v5) values(8003, 3, 9, 7, 14) 
insert #data(v1, v2, v3, v4, v5) values(8000, 4, 10, 8, 11) 
insert #data(v1, v2, v3, v4, v5) values(8001, 5, 11, 9, 12) 
insert #data(v1, v2, v3, v4, v5) values(8002, 6, 12, 7, 13) 
insert #data(v1, v2, v3, v4, v5) values(8003, 7, 13, 8, 14) 
insert #data(v1, v2, v3, v4, v5) values(8000, 3, 14, 9, 11) 
insert #data(v1, v2, v3, v4, v5) values(8001, 4, 8, 7, 12) 
insert #data(v1, v2, v3, v4, v5) values(8002, 5, 9, 8, 13) 
insert #data(v1, v2, v3, v4, v5) values(8003, 6, 10, 9, 14) 
insert #data(v1, v2, v3, v4, v5) values(8000, 7, 11, 7, 11) 
insert #data(v1, v2, v3, v4, v5) values(8001, 3, 12, 8, 12) 
insert #data(v1, v2, v3, v4, v5) values(8002, 4, 13, 9, 13) 
insert #data(v1, v2, v3, v4, v5) values(8003, 5, 14, 7, 14) 

select * from #data 

select v1, sum(v2) 
from #data 
    where v4 <= v3 and v5 > v3 
group by v1 

drop table #data 

在R,I已經嘗試使用骨料子集命令,骨料具有內聯函數(X)...,並且仍然沒有能夠聚結在所述數據我以純粹的'R'方式期待的方式。我知道SQL庫允許SQL語句在數據結構上進行事務處理,但我期望避免這種情況,因爲我首先從數據庫中提取數據,如果我需要求助於此,我不妨寫SQL來做到這一點。我正在尋找一種純粹的R做法。也許這有點理想化,但那是希望和夢想。

有一點需要注意的是,這是一個排除性條款,用於總結當前行中V2變量未包含的數據。否則,對我來說,這將是一個相當簡單的問題,但我並不認爲將審查的價值觀中的當前行傳遞給更大的數據集的功能,或者如果另一種解決方案會更好。

在此先感謝您的幫助。

這裏是R代碼以生成測試數據:

m.data <- as.data.frame(
     cbind(8000:8003, 3:7, 8:14, 7:9, 11:14, 1:28), 
     row.names=NULL 
); 
+0

爲什麼不向我們顯示R中的數據?如果你提供'dput(foo)'的輸出,這將有所幫助,其中'foo'是R中包含你顯示的數據的對象。 '聚合(子集(foo,v4 <= v3 & v5 > v3),by = list(v1),FUN = sum)'會乍一看似乎是想要的...... –

+0

這個問題與1)數據集是巨大的,2)原始數據集中的信息不適合我泄露,但如果解決了這個例子,它將基本解決我所問的問題。但是,我將在R中發佈上述內容,因此至少您可以更輕鬆地加載樣本數據。 –

+0

好的,在評論中發佈它並不是很好,所以我會將它添加到上面的代碼中。 –

回答

4

下面是示出什麼加文中的註釋中所述的玩具例如:

dd <- data.frame(v1 = rep(1:4,5),v2 = 1:20, 
       v3 = runif(20), v4 = runif(20), v5 = runif(20)) 

#Extract the subset 
dd_new <- subset(dd,v4 <= v3 & v5 > v3) 

#Using the aggregate command... 
> aggregate(dd_new$v2,list(v1=dd_new$v1),sum) 
    v1 x 
1 1 14 
2 2 18 
3 3 41 
4 4 16 

#Or the often popular ddply from plyr 
> ddply(dd_new,.(v1),summarise,tot = sum(v2)) 
    v1 tot 
1 1 14 
2 2 18 
3 3 41 
4 4 16 

我從凝集分裂該子集用於清晰度,但正如Gavin所表示的,如果你願意,你可以把它全部捲成一條線。

+0

看起來不錯,我會嘗試原始數據集併發布結果。 –

+0

@TraivsRodman很高興聽到它。你也知道,我們要求可重複使用的例子的原因是什麼(請看我在答案中做了什麼?這就是你的問題本應該是這樣的!)是爲了避免這種反覆的:我想一個答案,你檢查並回報。當你不可避免地說它不起作用時,我必須再次猜測。所以我希望你發現這個有用,但如果它不起作用,你想要更多的幫助,你必須編輯你的問題,包括一個可重複的例子。 – joran

+0

喬蘭 - 感謝您發佈的信息... @Gavin - 抱歉來回,感謝您花時間回答問題。 這完全解決了這個問題。以您描述的方式包含子集提供了正確的返回數據。我試圖讓這個子集成爲一個內聯的參數,但它並不是出於任何原因而工作,但是這個代碼完全按照我的希望工作。 謝謝。 –

1

如果您是SQL-junkie,請嘗試sqldf。對於大型數據集非常有效。請注意,我使用mdata而不是m.data,它需要在SQL中轉義。

library(sqldf) 
mdata <- as.data.frame(
     cbind(8000:8003, 3:7, 8:14, 7:9, 11:14, 1:28), 
     row.names=NULL 
); 
sqldf("select v1, sum(v2) from mdata where v4 <= v3 and v5 > v3 group by v1")