使用“累加”将列表中的 Dataframe 反连接到原始先前 Dataframe

eqoofvh9  于 2023-03-20  发布在  其他
关注(0)|答案(2)|浏览(99)

我有一个 Dataframe abc的列表。我希望最后得到一个列表,其中a不会更改,b仅包含不在a中的行,c仅包含不在b中的行。

# Sample data
a <- data.frame(num = 1:4, let = letters[1:4])
b <- data.frame(num = 2:6, let = letters[2:6])
c <- data.frame(num = 3:8, let = letters[3:8])

dfs <- list(a, b, c)

让我感到困惑的是我需要在 original previous Dataframe 上执行anti-join,而不是在对它的previous Dataframe 执行anti-join之后创建的 Dataframe 。我的直觉是使用purrr中的accumulate来完成这个任务,但是我不知道如何让它在original previous Dataframe 上工作。

dfs |> 
  accumulate(~anti_join(.y, .x))

[[1]]
  num let
1   1   a
2   2   b
3   3   c
4   4   d

[[2]]
  num let
1   5   e
2   6   f

[[3]]
  num let
1   4   d
2   7   g
3   8   h

由于这个连接在已经连接的前一个 Dataframe 上,所以我在第三个df中有我不想要的4 d
我尝试过.dir = "backward"作为使用原始dfs进行加入的一种方式,但这并没有做我认为它应该做的事情:

dfs |> 
   accumulate(~anti_join(.y, .x), .dir = "backward")

[[1]]
  num let
1   7   g
2   8   h

[[2]]
  num let
1   7   g
2   8   h

[[3]]
  num let
1   4   d
2   5   e
3   6   f
4   7   g
5   8   h

有没有办法设置accumulate的参数,这样它就可以做到这一点,或者我需要一个不同的方法?如果可能的话,我更喜欢purrr/tidyverse,但我愿意接受任何能满足我需要的东西。
预期产出:

[[1]]
  num let
1   1   a
2   2   b
3   3   c
4   4   d

[[2]]
  num let
1   5   e
2   6   f

[[3]]
  num let
1   7   g
2   8   h
crcmnpdw

crcmnpdw1#

您可以使用accumulate2来实现滚动anti_join

accumulate2(dfs, head(dfs, -1), ~ anti_join(..2, ..3))
[[1]]
  num let
1   1   a
2   2   b
3   3   c
4   4   d

[[2]]
  num let
1   5   e
2   6   f

[[3]]
  num let
1   7   g
2   8   h
wribegjk

wribegjk2#

**编辑:**使用map2

dfs[-1] <- map2(dfs[-1], dfs[-length(dfs)], anti_join)
[[1]]
  num let
1   1   a
2   2   b
3   3   c
4   4   d

[[2]]
  num let
1   5   e
2   6   f

[[3]]
  num let
1   7   g
2   8   h

accumulate用于动态排序,这里需要一个锚点df[[1]]和一个函数来应用于列表的其余元素:

dfs[-1] <- map(dfs[-1], ~ anti_join(.x, dfs[[1]]))

相关问题