在R中根据条件向数据框添加多个新列

4
假设我有一个数据集,长这样:
library(tidyverse)

df_raw <- data.frame(id = paste0('id', sample(c(1:13), replace = TRUE)), startTime = as.Date(rbeta(13, 0.7, 10) * 100, origin = "2016-01-01"), Channel = paste0('c', sample(c(1:3), 13, replace = TRUE, prob = c(0.2, 0.12, 0.3))) ) %>%
  group_by(id) %>%
  mutate(totals_transactions = sample(c(0, 1), n(), prob = c(0.9, 0.1), replace = TRUE)) %>%
  ungroup() %>%
  arrange(id, startTime)

现在我想把相同的id汇总在一起,并向这个新的数据框添加列,指示该id是否使用某个频道。我是这样做的:
seq_summaries <- df_raw %>%
  group_by(id) %>%
  summarize(
    c1_touches = max(ifelse(Channel == "c1",1,0)),
    c2_touches = max(ifelse(Channel == "c2",1,0)),
    c3_touches = max(ifelse(Channel == "c3",1,0)),
    conversions = sum(totals_transactions)
  ) %>% ungroup()

然而,我正在寻找一种方法,不需要手动为每个频道创建列,因为频道的数量可能会远超过三个,这将导致很多工作量。

1
你应该使用 dput(data) 来发布数据,而不是代码,特别是如果你没有使用基本的 R。dmap_at 是从哪里来的? - CPak
1
@CPak 我认为这是来自 purrrly,但是原帖已经删除了那一行,所以现在不需要 purrrly 了。 - www
1个回答

2

这里有一个想法。注意到你的数据框中没有任何c2。要使用complete函数,你仍然需要提供完整的c列表(从c1c3)。

library(tidyverse)

df2 <- df_raw %>%
  group_by(id, Channel) %>%
  summarize(
    touches = 1L,
    conversions = as.integer(sum(totals_transactions))
  ) %>% 
  ungroup() %>%
  complete(Channel = paste0("c", 1:3)) %>%
  spread(Channel, touches, fill = 0L) %>%
  drop_na(id) %>%
  select(id, paste0("c", 1:3), conversions)
df2
# # A tibble: 8 x 5
#   id       c1    c2    c3 conversions
#   <fct> <int> <int> <int>       <int>
# 1 id10      1     0     0           0
# 2 id11      0     0     1           0
# 3 id12      0     0     1           1
# 4 id2       0     0     1           0
# 5 id3       0     0     1           0
# 6 id6       1     0     0           0
# 7 id8       1     0     0           1
# 8 id9       0     0     1           0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接