【问题标题】:Contingency table based on third variable (numeric)基于第三个变量(数字)的列联表
【发布时间】:2013-10-31 11:31:25
【问题描述】:

前段时间我问了一个关于创建购物篮数据的问题。现在我想创建一个类似的 data.frame,但基于第三个变量。不幸的是,我在尝试时遇到了问题。上一个问题:Effecient way to create market basket matrix in R
@shadow 和 @SimonO101 给了我很好的答案,但我无法正确更改他们的答案。我有以下数据:

Customer <- as.factor(c(1000001,1000001,1000001,1000001,1000001,1000001,1000002,1000002,1000002,1000003,1000003,1000003))
Product <- as.factor(c(100001,100001,100001,100004,100004,100002,100003,100003,100003,100002,100003,100008))
input <- data.frame(Customer,Product)

我现在可以通过以下方式创建列联表:

input_df <- as.data.frame.matrix(table(input))

但是我有第三个(数字)变量,我想在表中作为输出。

Number <- c(3,1,-4,1,1,1,1,1,1,1,1,1) 
input <- data.frame(Customer,Product,Number)

现在代码(当然,现在有 3 个变量)不再起作用了。我正在寻找的结果具有唯一的客户作为行名和唯一的产品作为列名。并且有 Number 作为值(如果不存在,则为 0),该数字可以通过以下方式计算:

input_agg <- aggregate( Number ~ Customer + Product, data = input, sum)

希望我的问题很清楚,如果有不清楚的地方请评论。

【问题讨论】:

  • +1 是另一个可重现的例子。
  • 你能成功完成aggregate这一步吗?

标签: r


【解决方案1】:

此类问题专为reshape2::dcast...

require( reshape2 )
#  Too many rows so change to a data.table.
dcast( input , Customer ~ Product , fun = sum , value.var = "Number" )
#  Customer 100001 100002 100003 100004 100008
#1  1000001      0      1      0      2      0
#2  1000002      0      0      3      0      0
#3  1000003      0      1      1      0      1

最近,dcastdata.table 对象一起使用的方法是由@Arun 响应FR #2627 实现的。好东西。您必须使用开发版本1.8.11。目前,它应该用作dcast.data.table。这是因为dcast 还不是reshape2 包中的S3 泛型。也就是说,你可以这样做:

require(reshape2)
require(data.table)
input <- data.table(input)   
dcast.data.table(input , Customer ~ Product , fun = sum , value.var = "Number")
#    Customer 100001 100002 100003 100004 100008
# 1:  1000001      0      1      0      2      0
# 2:  1000002      0      0      3      0      0
# 3:  1000003      0      1      1      0      1

这应该可以很好地处理更大的数据,并且应该比reshape2:::dcast 快得多。


或者,您可以尝试reshape:::cast 版本,它可能会崩溃也可能不会崩溃...试试吧!!

require(reshape)
input <- data.table( input )
cast( input , Customer ~ Product , fun = sum , value = .(Number) )

【讨论】:

  • 快速响应,这确实有效。但是,它使我的 R 会话立即崩溃。我更新了我的问题。
  • @Freddy 查看更新。使用data.table。已经为这些编写了 dcast 方法。应该很快,避免让你的电脑崩溃!
  • @Freddy 但使用data.table 而不是data.frame?这是一个重要的区别!此外,如果您不将输出分配给变量,它将尝试打印到控制台并且可能会崩溃,因此请尝试复制/粘贴此...input &lt;- data.table( input ); output &lt;- dcast( input , Customer ~ Product , fun = sum , value.var = "Number" )
  • 嗯,你为什么不尝试使用数据的子集,例如第一个100k 行?例如dcast( input[ 1:1e5 , ] ... ) 看看这是否可行并从那里建立起来?
  • @Freddy 也许你看到this problem...太多的组。
【解决方案2】:

您可以为此使用 xtabs

R> xtabs(Number~Customer+Product, data=input)

         Product
Customer  100001 100002 100003 100004 100008
  1000001      0      1      0      2      0
  1000002      0      0      3      0      0
  1000003      0      1      1      0      1

【讨论】:

  • @SimonO101 其实我才发现的:-)
  • 我认为这不是效率问题,而是系统上有多少 RAM 的问题。无论你用什么方法来计算它,你最终都会得到一个 90000x2000 的表来存储在内存中......
  • @juba,这确实是正确的,应该知道它不适合。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-20
  • 1970-01-01
  • 1970-01-01
  • 2016-09-20
  • 1970-01-01
  • 1970-01-01
  • 2021-05-17
相关资源
最近更新 更多