【问题标题】:Combine two datasets covering all the possible combinations合并两个数据集,涵盖所有可能的组合
【发布时间】:2020-06-09 21:36:02
【问题描述】:

我在执行连接操作时遇到问题。

我的两个数据框是:

library(tidiverse)
df_one <- data.frame(
                cohort = c("2019-03-01", "2019-03-01", "2019-03-01", "2019-04-01",
                           "2019-04-01", "2019-05-01"),
               periods = c(1, 2, 3, 1, 2, 1),
                 value = c(13, 24, 35, 22, 38, 21)
          )

df_two <- data.frame(
               periods = c(1, 2, 3, 4),
               value_2 = c(100, 73, 45, 29)
          )

我想要实现的最终结果是一个连接的数据框,其中包含df_two 中的所有可能组合 - 对df_one 中的元素重复 - 如下:

df_final <- data.frame(
                  cohort = c("2019-03-01", "2019-03-01", "2019-03-01", "2019-03-01",
                             "2019-04-01", "2019-04-01", "2019-04-01",
                             "2019-04-01", "2019-05-01", "2019-05-01", "2019-05-01",
                             "2019-05-01"),
                 periods = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4),
                   value = c(13, 24, 35, NA, 22, 38, NA, NA, 21, NA, NA, NA),
                 value_2 = c(100, 73, 45, 29, 100, 73, 45, 29, 100, 73, 45, 29)
            )

       cohort periods value value_2
1  2019-03-01       1    13     100
2  2019-03-01       2    24      73
3  2019-03-01       3    35      45
4  2019-03-01       4    NA      29
5  2019-04-01       1    22     100
6  2019-04-01       2    38      73
7  2019-04-01       3    NA      45
8  2019-04-01       4    NA      29
9  2019-05-01       1    21     100
10 2019-05-01       2    NA      73
11 2019-05-01       3    NA      45
12 2019-05-01       4    NA      29

我尝试使用crossing():

crossing(df_one, df_two)

但我得到了错误:

Error: Column name `periods` must not be duplicated.
Run `rlang::last_error()` to see where the error occurred.

一旦修复了唯一列名 - 正如用户 @akrun 所建议的那样 - 通过:

crossing(df_one, df_two, .name_repair = "unique")

我意识到crossing() 不会产生我想要的结果。

我应该遵循什么方法来获得df_final?

【问题讨论】:

  • 我不是故意让任何人看起来像傻瓜。我的问题是如何从两个初始数据帧df_one 和df_two 开始获得输出df_final。我试图用crossing() 来解决它——错误地——我寻求帮助,绝对无意冒犯任何人@akrun
  • 我再次编辑了这个问题 - 指定您对crossing() 抛出的错误的更正,我希望现在它可以更好地澄清我的要求@akrun

标签: r join dplyr tidyverse


【解决方案1】:

crossing 需要唯一的列名,“句点”是重复的。根据?crossing

crossing(..., .name_repair = "check_unique")

这意味着默认选项将检查唯一的列名,如果有重复,则会抛出错误。

library(dplyr)
library(tidyr)
library(stringr)

我们可以更改.name_repair 以强制列名“唯一”

crossing(df_one, df_two, .name_repair = "unique")
#New names:
#* periods -> periods...2
#* periods -> periods...4
# A tibble: 24 x 5
#   cohort     periods...2 value periods...4 value_2
#   <chr>            <dbl> <dbl>       <dbl>   <dbl>
# 1 2019-03-01           1    13           1     100
# 2 2019-03-01           1    13           2      73
# 3 2019-03-01           1    13           3      45
# 4 2019-03-01           1    13           4      29
# 5 2019-03-01           2    24           1     100
# 6 2019-03-01           2    24           2      73
# 7 2019-03-01           2    24           3      45
# 8 2019-03-01           2    24           4      29
# 9 2019-03-01           3    35           1     100
#10 2019-03-01           3    35           2      73
# … with 14 more rows

或者使用“最小”来保留重复的列名(但从长远来看这会使事情变得更加复杂


为了达到预期,我们可以通过complete 在第一个数据集上进行分组,然后在第二个数据集上使用left_join

df_one %>% 
   group_by(cohort) %>%
   complete(periods = df_two$periods) %>%
   left_join(df_two)
# A tibble: 12 x 4
# Groups:   cohort [3]
#   cohort     periods value value_2
#   <chr>        <dbl> <dbl>   <dbl>
# 1 2019-03-01       1    13     100
# 2 2019-03-01       2    24      73
# 3 2019-03-01       3    35      45
# 4 2019-03-01       4    NA      29
# 5 2019-04-01       1    22     100
# 6 2019-04-01       2    38      73
# 7 2019-04-01       3    NA      45
# 8 2019-04-01       4    NA      29
# 9 2019-05-01       1    21     100
#10 2019-05-01       2    NA      73
#11 2019-05-01       3    NA      45
#12 2019-05-01       4    NA      29

【讨论】:

  • 我了解穿越的工作原理。但可能这不是正确的解决方案,因为它最终没有给我我想要的df_final。我应该使用不同的功能吗? @akrun
  • @xxxvincxxx 我认为您的问题是如何更改错误。无论如何
  • 很抱歉造成误解。我试图尝试使用crossing 得到一个错误,但现在查看结果我意识到这是错误的方法。我正在相应地编辑问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-09
  • 2018-03-15
  • 1970-01-01
  • 1970-01-01
  • 2016-10-19
  • 2012-03-27
  • 1970-01-01
相关资源
最近更新 更多