我遇到了以下问题(这实际上是两个问题):我有一个带有事务的csv文件。但是使用transactionID购买的所有商品都存储在单个单元格的多行中。
看起来像这样
TransactionID Items
1234 Milk
Butter
Bread
2345 Milk
Bread
3456 Beer
Milk
4567 Beer
Butter
正如您所看到的,并非所有项目都在每笔交易中使用。
如何将R中的数据导入为类似于此
的事务矩阵TransactionID Milk Butter Bread Beer
1234 1 1 1 0
2345 1 0 1 0
3456 1 0 0 1
4567 0 1 0 1
可以在一个优雅的步骤中完成吗? 导入后我想使用arules包分析我的数据。
提前致谢!
答案 0 :(得分:1)
这不是单行,并假设单词被空格分割。我首先找到独特的单词,然后进行双循环。
u <- unique(do.call('c', strsplit(df$items, ' ')))
for (i in 1:nrow(df)) {
for (j in u) {
df[i, j] <- 1 * (j %in% strsplit(df$items[i], ' ')[[1]])
}
}
答案 1 :(得分:0)
谢谢@DirkNachbar!你的方法起作用,并且明确地将我推向了正确的方向。只需要进行一些小的调整:这些单词被换行符分开。
之后我将矩阵添加到文件中,然后将其重新插入arules。
write(mat, file = "TransactionMatrix", sep = "\n")
trans = read.transactions("TransactionMatrix", format = "basket", sep = "\n")
关于这种方法的问题是运行时。有几万个交易和几千个项目,计算矩阵需要很长时间。
由于我的最终目标是导入arules的事务矩阵格式,我最终使用了另一种方法并将所有项目连接到一个大型列表。
df <- read.csv("Transactions.csv", header = TRUE, sep = ";", dec = ",")
MaxTransactions <- 0
for (i in 1:length(df$items)) {
add <- length(strsplit(as.character(df$items[i]),'\n')[[1]])
MaxTransactions <- MaxTransactions + add
}
IDs <- rep(NA, MaxTransactions)
ITEMs <- rep(NA, MaxTransactions)
Position <- 0
for (i in 1:length(df$items)) {
tempITEM <- c(strsplit(as.character(df$items[i]),'\n')[[1]])
tempID <- rep(as.character(df$TransID[i]),length(tempITEM))
for (j in 1:length(tempITEM)) {
IDs[Position+j] <- tempID[j]
ITEMs[Position+j] <- tempITEM[j]
}
Position <- Position + length(tempITEM)
}
这允许我从“交易”格式而不是“篮子”格式强制转换到arules的交易矩阵。
a_df <- data.frame(ID = as.factor(IDs),ITEM = as.factor(ITEMs))
TransList <- split(a_df[,"ITEM"],a_df[,"ID"])
TransMat <- as(TransList, "transactions")
这对我有用。