从 csv 到 R 事务矩阵的多行单元格
Multiple line cells from csv to R transaction matrix
我遇到了以下问题(实际上是两个问题):我有一个包含交易的 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 包分析我的数据。
提前致谢!
这不是单行,假设单词被空格分隔 space。我先找到独特的词然后做一个双循环。
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]])
}
}
谢谢@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)
}
这让我可以从 "transaction" 格式而不是 "basket" 格式强制转换为 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")
这对我来说效果很好。
我遇到了以下问题(实际上是两个问题):我有一个包含交易的 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 包分析我的数据。
提前致谢!
这不是单行,假设单词被空格分隔 space。我先找到独特的词然后做一个双循环。
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]])
}
}
谢谢@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)
}
这让我可以从 "transaction" 格式而不是 "basket" 格式强制转换为 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")
这对我来说效果很好。