dplyr:在列表列中构建一组项目

时间:2018-04-11 22:34:08

标签: r dplyr purrr

我想要一个列,它根据谓词跟踪集合中包含的项目。看起来我应该能够使用purrr <script src="https://unpkg.com/vue"></script> <div id="app" v-html="html"> </div>函数和dplyr accumulatelead/lag函数的某种组合来完成此操作。

这可能最好表达为一个代表:

union/setdiff

编辑:我非常接近。我需要找到一种找到&#34;袋差异的方法&#34; (例如,在用户包括,排除然后重新包括项目的情况下,向量之间的(而不是设定差异)。

input_df <- dplyr::data_frame(user = c("1", "1", "1", "1"),
                              item = c("a", "b", "a", "a"),
                              include = c(TRUE, TRUE, FALSE, TRUE))

output_df <- dplyr::data_frame(user = c("1", "1", "1", "1"),
                               set = list(
                                 c("a"),
                                 c("a", "b"),
                                 c("b"),
                                 c("a", "b")))

1 个答案:

答案 0 :(得分:1)

定义Update,其中使用第i个项目获取篮子的union或setdiff,并使用Reduce将其应用于每个i。使用ave按用户执行所有操作。没有包使用。

Update <- function(basket, i) with(input_df[i, ],
      (if (include) union else setdiff)(basket, item)
)

n <- nrow(input_df)
reduce_user <- function(ix) Reduce(Update, init = NULL, ix, accumulate = TRUE)[-1]

transform(input_df["user"], set = I(ave(as.list(1:n), user, FUN = reduce_user)))

,并提供:

  user  set
1    1    a
2    1 a, b
3    1    b
4    1 b, a

或者,将上述内容翻译成dplyr和purrr并使用上面的Update,我们得到以下代码。

library(dplyr)
library(purrr)

input_df %>%
  mutate(ix = 1:n()) %>%
  group_by(user) %>%
  mutate(set = accumulate(ix, Update, .init = NULL)[-1]) %>%
  ungroup %>%
  select(user, set)

(请注意,purrr的唯一用途是accumulate,如果您想减少依赖项,可以很容易地用Reduce替换。)