我有一个带有 id 号的数据框、一个产品变量和一个虚拟变量,用于说明产品是否已被购买。
set.seed(2019)
library(dplyr)
library(data.table)
df <- data.frame(id = rep.int(c(1:5), 5),
bought = 1) %>%
group_by(id) %>%
mutate(product = c("244.1","455.2","266.3","777.4","111.1"))
除此之外,我还有一个向量,其中包含我知道尚未购买的产品,我想将其添加到数据框中。
products <- c("100.4", "500.1", "200.1", "121.6", "251.7", "215.1", "172.2")
也就是说,对于每个用户,我想要非购买的产品并设置购买 = 0。
一种方法是从向量中创建一个数据框并将其绑定到原始数据框。
products <- data.frame(product = products)
products$id <- NA
products$bought <- 0
products <- products[, c(2, 3, 1)]
df <- bind_rows(df, products)
#> Warning in bind_rows_(x, .id): binding character and factor vector,
#> coercing into character vector
然后我可以data.table
用来完成表格,转动每一个NA = 0
,如果我想过滤掉每一个观察id = NA
。(我也可以使用tidyr::complete()
,但原始 data.frame 非常大,所以我更喜欢data.table
)
setDT(df)[CJ(id = id, product = product, unique = TRUE), on = .(id, product)][
is.na(bought), bought := 0][]
#> id bought product
#> 1: NA 0 100.4
#> 2: NA 0 111.1
#> 3: NA 0 121.6
#> 4: NA 0 172.2
#> 5: NA 0 200.1
#> 6: NA 0 215.1
#> 7: NA 0 244.1
#> 8: NA 0 251.7
#> 9: NA 0 266.3
#> 10: NA 0 455.2
#> 11: NA 0 500.1
#> 12: NA 0 777.4
#> 13: 1 0 100.4
#> 14: 1 1 111.1
#> 15: 1 0 121.6
但是,从向量创建 data.frame 的方法似乎相当冗长,我宁愿不添加带有id = NA
. 有没有更巧妙的方法将矢量与 data.frame 结合起来并完成它?
由reprex 包(v0.2.1)于 2019 年 1 月 8 日创建
使用 data.table 的简单解决方案:
products <- c("100.4", "500.1", "200.1", "121.6", "251.7", "215.1", "172.2")
df <- setDT(df)
rbindlist(lapply(unique(df$id),function(ID){
rbind(df[id == ID],data.table(product = products,id = ID, bought = 0))
}))
您还可以考虑使用该 dtaa 框架合并两个数据框架:
products <- data.frame(product = rep(products,each = length(unique(df$id))),
id = rep(unique(df$id),length(unique(products))))
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句