R 将篮子数据帧融化为单个数据帧,无循环
我有一个篮子格式的数据帧,如下所示:R 将篮子数据帧融化为单个数据帧,无循环,r,market-basket-analysis,R,Market Basket Analysis,我有一个篮子格式的数据帧,如下所示: V1 <- c('milk', 'beer', 'wrench', 'milk' ) V2 <- c('eggs', 'elbow grease', '', 'beer') V3 <- c('water', '', '', '') df <- data.frame(V1, V2, V3) 我想制作一个单一格式的数据帧,如下所示: transaction product 1 1 milk 2
V1 <- c('milk', 'beer', 'wrench', 'milk' )
V2 <- c('eggs', 'elbow grease', '', 'beer')
V3 <- c('water', '', '', '')
df <- data.frame(V1, V2, V3)
我想制作一个单一格式的数据帧,如下所示:
transaction product
1 1 milk
2 1 eggs
3 1 water
4 2 beer
5 2 elbow grease
6 3 wrench
7 4 milk
8 4 beer
现在,我想要数据帧中的数据,以便在切换到apriori R包使用的事务格式之前进行过滤
将此数据帧从篮子转换为单一格式的最快方法是什么
现在我正在使用一个非常慢的循环
dfSingle <- data.frame(product = character(),
transaction = integer())
for (row in 1:nrow(df)) {
# Create a list of products
productList <- unname(unlist(df[row, ]))
# Remove blank spaces
productList <- productList[!productList %in% ""]
# Convert to a dataframe
dfTemp <- as.data.frame(productList)
colnames(dfTemp) <- "product"
dfTemp$transaction <- row
# Bind to larger dataframe with previous rows
dfSingle <- rbind(dfSingle, dfTemp)
}
dfSingle您可以使用stack
。诀窍是转置数据帧,即
df1 <- stack(as.data.frame(t(df), stringsAsFactors = FALSE))
df1[df1$values != '',]
values ind
#1 milk V1
#2 eggs V1
#3 water V1
#4 beer V2
#5 elbow grease V2
#7 wrench V3
#10 milk V4
#11 beer V4
这将给
使用tidyverse
可以执行以下操作:
df %>%
mutate_all(funs(ifelse(. == "", NA_character_, paste0(.)))) %>%
rowid_to_column(var = "transaction") %>%
gather(var, product, -transaction, na.rm = TRUE) %>%
select(-var) %>%
arrange(transaction)
transaction product
1 1 milk
2 1 eggs
3 1 water
4 2 beer
5 2 elbow grease
6 3 wrench
7 4 milk
8 4 beer
首先,它用NA_字符替换空行。其次,它创建了一个行ID为“transaction”的变量。第三,它将数据从宽格式转换为长格式,并删除带有NA_字符的行。最后,它根据“事务”或data.table方法排列数据
(一班轮)
首先从以下行名称获取事务:setDT(df)[,事务:=.I]
然后使用事务作为id列进行熔化:melt(…,id=“transaction”)
最后删除空值并返回第一列和第三列:…[!value==”,c(1,3)]
将字符“
替换为适当的格式NA
后,可以创建一个新的列事务,然后使用重塑2::melt
:
df[df == ""] <- NA
df$transaction <- 1:nrow(df)
此函数的好处是,它将为您提供一个列变量
,它将为您提供上一个df
data.frame的列的名称。如果它与您无关,则使用另一个基础R
备选方案删除此列:
do.call(
rbind,
sapply(seq_along(df), function(i) cbind(transaction = i, product = df[[i]][nzchar(df[[i]])]))
)
transaction product
[1,] "1" "milk"
[2,] "1" "beer"
[3,] "1" "wrench"
[4,] "1" "milk"
[5,] "2" "eggs"
[6,] "2" "elbow grease"
[7,] "2" "beer"
[8,] "3" "water"
接受这个答案,因为它作为数据表运行得最快
df %>%
mutate_all(funs(ifelse(. == "", NA_character_, paste0(.)))) %>%
rowid_to_column(var = "transaction") %>%
gather(var, product, -transaction, na.rm = TRUE) %>%
select(-var) %>%
arrange(transaction)
transaction product
1 1 milk
2 1 eggs
3 1 water
4 2 beer
5 2 elbow grease
6 3 wrench
7 4 milk
8 4 beer
melt( setDT(df)[, transaction := .I ], id = "transaction" )[!value == "", c(1,3) ]
# transaction value
# 1: 1 milk
# 2: 2 beer
# 3: 3 wrench
# 4: 4 milk
# 5: 1 eggs
# 6: 2 elbow grease
# 7: 4 beer
# 8: 1 water
df[df == ""] <- NA
df$transaction <- 1:nrow(df)
melted_df <- na.omit(reshape2::melt(data=df, id.vars="transaction"))
> melted_df
transaction variable value
1 1 V1 milk
2 2 V1 beer
3 3 V1 wrench
4 4 V1 milk
5 1 V2 eggs
6 2 V2 elbow grease
8 4 V2 beer
9 1 V3 water
out <- melted_df[order(melted_df$transaction), ]
> out
transaction value
1 1 milk
5 1 eggs
9 1 water
2 2 beer
6 2 elbow grease
3 3 wrench
4 4 milk
8 4 beer
do.call(
rbind,
sapply(seq_along(df), function(i) cbind(transaction = i, product = df[[i]][nzchar(df[[i]])]))
)
transaction product
[1,] "1" "milk"
[2,] "1" "beer"
[3,] "1" "wrench"
[4,] "1" "milk"
[5,] "2" "eggs"
[6,] "2" "elbow grease"
[7,] "2" "beer"
[8,] "3" "water"