2012-06-14 56 views
3

我不知道是否有人有一個想法,如何以更好的方式計算組合如下,比我想象的。計數組合不破壞類型

> library(lubridate) 
> df <- data.frame(x=sample(now()+hours(1:3), 100, T), y=sample(1:4, 100, T)) 
> with(df, as.data.frame(table(x, y))) 
        x y Freq 
1 2012-06-15 00:10:18 1 5 
2 2012-06-15 01:10:18 1 9 
3 2012-06-15 02:10:18 1 8 
4 2012-06-15 00:10:18 2 9 
5 2012-06-15 01:10:18 2 10 
6 2012-06-15 02:10:18 2 12 
7 2012-06-15 00:10:18 3 7 
8 2012-06-15 01:10:18 3 9 
9 2012-06-15 02:10:18 3 6 
10 2012-06-15 00:10:18 4 5 
11 2012-06-15 01:10:18 4 14 
12 2012-06-15 02:10:18 4 6 

我喜歡這種格式,但不幸的是,當我們通過table()xy,他們得到了轉化爲因素。在最終的輸出中,它們可以很好地存在,因爲它們的原始類型,但是到達那裏似乎存在問題。目前我只是後來手動修復所有類型,這是非常麻煩的,因爲我必須重新設置時區,並查找默認日期格式的百分號等。等等。

看起來像一個高效解決方案將涉及散列對象,或者將整數映射到唯一值xy,因此我們可以使用tabulate(),然後映射回來。

想法?

回答

5

這裏的data.table版本保留列類:響應

library(data.table) 

dt <- data.table(df, key=c("x", "y")) 
dt[, .N, by=key(dt)] 
#      x y N 
# 1: 2012-06-14 18:10:22 1 8 
# 2: 2012-06-14 18:10:22 2 10 
# 3: 2012-06-14 18:10:22 3 8 
# 4: 2012-06-14 18:10:22 4 8 
# 5: 2012-06-14 19:10:22 1 6 
# 6: 2012-06-14 19:10:22 2 8 
# 7: 2012-06-14 19:10:22 3 6 
# 8: 2012-06-14 19:10:22 4 6 
# 9: 2012-06-14 20:10:22 1 15 
# 10: 2012-06-14 20:10:22 2 5 
# 11: 2012-06-14 20:10:22 3 12 
# 12: 2012-06-14 20:10:22 4 8 

str(dt[, .N, by=key(dt)]) 
# Classes ‘data.table’ and 'data.frame': 12 obs. of 3 variables: 
# $ x: POSIXct, format: "2012-06-14 18:10:22" "2012-06-14 18:10:22" ... 
# $ y: int 1 2 3 4 1 2 3 4 1 2 ... 
# $ N: int 8 10 8 8 6 8 6 6 15 5 ... 

編輯後續問題

要計算的所有可能的組合所觀察到的因子水平(包括出現數那些沒有出現在數據中),你可以做如下事情:

dt<-dt[1:30,] # Make subset of dt in which some factor combinations don't appear 

ii <- do.call("CJ", lapply(dt, unique)) # CJ() is similar to expand.grid() 
dt[ii, .N] 
#      x y N 
# 1: 2012-06-14 22:53:05 1 8 
# 2: 2012-06-14 22:53:05 2 7 
# 3: 2012-06-14 22:53:05 3 9 
# 4: 2012-06-14 22:53:05 4 5 
# 5: 2012-06-14 23:53:05 1 1 
# 6: 2012-06-14 23:53:05 2 0 
# 7: 2012-06-14 23:53:05 3 0 
# 8: 2012-06-14 23:53:05 4 0 
+0

非常好。我幾乎將*批量切換到'data.table',但從未真正實現過飛躍。也許我應該。 –

+0

實際上 - 當我使用3個鍵'x,y,z'運行代碼而不是僅僅運行兩個代碼時,它會抱怨'object'.N'not found'。在我的真實數據中,我有3個鍵,但是我把這個問題歸結爲2,認爲這並不重要。有沒有關於'.N',使它不可用3鍵? –

+0

糟糕 - 我的不好,它工作正常。我錯誤地複製了一個變量名。 –

3

您可以使用ddply

library(plyr) 

ddply(df, .(x, y), summarize, Freq = length(y)) 

如果你想讓它安排的y然後x

ddply(df, .(y, x), summarize, Freq = length(y)) 

,或者如果列順序是重要的,以及行排序

arrange(ddply(df, .(x, y), summarize, Freq = length(y)), y) 
+0

對不起,我應該提到'ddply()'實際上是我寫這個的第一種方式。不幸的是,它比'table()'方法慢。有意義的是,'table()'只是列表計數,而'ddply()'必須實際提取所有相關數據並將其提供給函數。 –

+0

我沒有意識到效率是目標。 'data.table'絕對是一種可行的方式。我目前正在將自己從'plyr'轉換爲'data.table'。 – mnel

+0

是的,我應該在我的問題中更清楚。雖然我很高興看到這個解決方案使用'summarize',但我不知道這個功能。 FWIW,它也適用於'ddply(df,。(x,y),nrow)',但列名不太好。 –