我使用客户购买篮子的数据集。以下是它的一个示例:
basket item quant
1 1 B 1
2 1 A 2
3 1 C 1
4 2 A 1
5 2 C 1
6 3 A 2
7 4 B 1
8 4 C 1
以下是复制它的代码:
input <- data.frame(
basket = c(1,1,1,2,2,3,4,4),
item = c("B","A","C","A","C","A","B","C"),
quant=c(1,2,1,1,1,2,1,1)
)
所以在第一个篮子中有三个具有指定数量的物品。我有一个自定义功能,只适用于特定格式的输入;我们定义最大篮子大小。让我们说它是5.现在该函数的输入应该是这样的:
basket item_1 item_2 item_3 item_4 item_5
1 1 B A A C <NA>
2 2 A C <NA> <NA> <NA>
3 3 A A <NA> <NA> <NA>
4 4 B C <NA> <NA> <NA>
我一直试图使用dplyr
和summarise
来做,但没有运气。
任何帮助将不胜感激!
答案 0 :(得分:2)
这是tidyverse
的想法。这里的技巧是根据quant
复制您的行,然后删除quant
变量,这样它就不会让您重新整理到宽数据框。之后,您创建一个new
变量来处理重复项,当然最后spread
来获取所需的宽数据框。
library(tidyverse)
df[rep(rownames(df), df$quant),] %>%
select(-quant) %>%
group_by(basket) %>%
mutate(new = paste0('item_', row_number())) %>%
spread(new, item)
给出,
# A tibble: 4 x 5 # Groups: basket [4] basket item_1 item_2 item_3 item_4 <dbl> <fct> <fct> <fct> <fct> 1 1. B A A C 2 2. A C NA NA 3 3. A A NA NA 4 4. B C NA NA
答案 1 :(得分:2)
另一种可能的解决方案:
library(dplyr)
library(tidyr)
input[rep(1:nrow(input), input$quant),] %>%
group_by(basket) %>%
mutate(item2 = paste0('item_', row_number())) %>%
complete(item2 = paste0('item_', 1:5)) %>%
select(-quant) %>%
spread(item2, item)
给出:
# A tibble: 4 x 6 basket item_1 item_2 item_3 item_4 item_5 <dbl> <fct> <fct> <fct> <fct> <fct> 1 1. B A A C NA 2 2. A C NA NA NA 3 3. A A NA NA NA 4 4. B C NA NA NA
使用相同的逻辑,但使用data.table
- 包:
library(data.table)
setDT(input)
input[input[, rep(.I, quant)]
][, .(basket, item, item2 = paste0('item_', rowid(basket)))
][CJ(basket = basket, item2 = paste0('item_', 1:5), unique = TRUE)
, on = .(basket, item2)
][, dcast(.SD, basket ~ item2, value.var = 'item')]