我想知道是否有人知道如何以比我想象的更好的方式对下列组合进行计数。
> 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
我喜欢这种格式,但遗憾的是,当我们通过x
运行y
和table()
时,它们已转换为因子。在最终输出中,它们可以作为原始类型存在得非常好,但是到达那里似乎存在问题。目前我只是手动修复所有类型,这非常麻烦,因为我必须重新设置时区,并查找默认日期格式的百分比代码等。
似乎有效的解决方案会涉及散列对象,或者将整数映射到x
和y
的唯一值,因此我们可以使用tabulate()
,然后映射回来。 / p>
想法?
答案 0 :(得分: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
答案 1 :(得分: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)