【问题标题】:Efficient way to create market basket matrix in R在 R 中创建市场篮子矩阵的有效方法
【发布时间】:2013-07-18 12:16:14
【问题描述】:

我正在尝试从如下所示的数据创建一个购物篮矩阵:

input <- matrix( c(1000001,1000001,1000001,1000001,1000001,1000001,1000002,1000002,1000002,1000003,1000003,1000003,100001,100002,100003,100004,100005,100006,100002,100003,100007,100002,100003,100008), ncol=2)

这代表以下数据:

colnames(input) <- c( "Customer" , "Product" )

由此创建了一个矩阵,其中一个客户为一行,所有产品为列。这可以通过首先创建这个带有零的矩阵来实现:

input <- as.data.frame(input)
m <- matrix(0, length(unique(input$Customer)), length(unique(input$Product)))
rownames(m) <- unique(input$Customer)
colnames(m) <- unique(input$Product)

这一切都足够快(有 750 000+ 行的数据,创建一个 15000 x 1500 矩阵),但现在我想在适当的地方填充矩阵:

for( i in 1:nrow(input) ) {
    m[ as.character(input[i,1]),as.character(input[i,2])] <- 1
}

我认为必须有一种更有效的方法来做到这一点,正如我从 stackoverflow 中了解到的那样,通常可以避免 for 循环。那么问题来了,有没有更快的方法呢?

我需要矩阵中的数据,因为我想使用像插入符号这样的包。在那之后,我可能会遇到与R memory management advice (caret, model matrices, data frames) 相同的问题,但这是以后的问题。

【问题讨论】:

  • 检查你input矩阵,那里缺少一个值,就在1000001, ,1000002之间

标签: r matrix


【解决方案1】:

您实际上并不需要reshape2table 是您正在寻找的。

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

all.equal(m, m1)
TRUE

【讨论】:

  • 或者只是unclass(table(input))。无论如何,+1,很好的答案
【解决方案2】:

reshape2 包有一个可以完成这项工作的转换函数:

require(reshape2)
m <- acast(input, Customer ~ Product,function(x) 1,fill=0)
m

给我

        100001 100002 100003 100004 100005 100006 100007 100008
1000001      1      1      1      1      1      1      0      0
1000002      0      1      1      0      0      0      1      0
1000003      0      1      1      0      0      0      0      1

我希望这就是您要找的东西?

【讨论】:

  • +1 我不知道这个。我正在考虑使用outer 和一些逻辑比较。
  • 虽然,@shadow 的回答鼓励我及时拍拍我的脸
【解决方案3】:

你可以使用稀疏矩阵:

library(Matrix)
input <- as.data.frame(apply(input,2,as.character))
m <- sparseMatrix( 
  i = as.numeric( input[,1] ),
  j = as.numeric( input[,2] ),
  x = 1,
  dim = c( length(levels(input[,1])), length(levels(input[,2])) ),
  dimnames = list( levels(input[,1]), levels(input[,2]) )
)
m
# 3 x 8 sparse Matrix of class "dgCMatrix"
#         100001 100002 100003 100004 100005 100006 100007 100008
# 1000001      1      1      1      1      1      1      .      .
# 1000002      .      1      1      .      .      .      1      .
# 1000003      .      1      1      .      .      .      .      1

【讨论】:

  • 我认为这个矩阵将使用更少的内存,但是你可以将这个矩阵与 caret 和 party 等包结合使用吗? (因为我认为那行不通)
  • 你应该尝试,但我认为它应该工作:所有操作都超载。但是,可能发生的是这些包使用矩阵来构建其他矩阵——这些可能是正常(密集)矩阵。如果它不起作用,您始终可以使用as.matrix 将稀疏矩阵转换为密集矩阵。
  • 谢谢,我一定会调查的。因为我的矩阵有很多 0,它会节省很多内存。如果我有更多的声誉,我会投票给你的评论;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-23
  • 1970-01-01
  • 2016-12-19
  • 1970-01-01
相关资源
最近更新 更多