将字符向量与data.frame结合起来并完成表格

时间:2019-01-08 12:22:39

标签: r data.table tidyr

我有一个带有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 package(v0.2.1)于2019-01-08创建

1 个答案:

答案 0 :(得分:1)

使用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))))