【问题标题】:When I use gather() twice, my resulting tibble is much larger than it should be当我使用 collect() 两次时,我得到的 tibble 比它应该的要大得多
【发布时间】:2018-03-10 13:59:53
【问题描述】:

我有一个美朝近20年进出口的tibble,很多列名都是月份的名称,IJAN代表进口月份,EJAN代表出口月份,所以我用了gather()两次尝试以正确的 tidydata 格式获取它们。

这是我原来的小标题:

      # A tibble: 26 x 29
   year  CTY_CODE CTYNAME    IJAN  IFEB  IMAR  IAPR  IMAY  IJUN  IJUL  IAUG  ISEP  IOCT  INOV  IDEC   IYR  EJAN  EFEB  EMAR  EAPR  EMAY  EJUN  EJUL  EAUG  ESEP
   <chr> <chr>    <chr>     <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1 1992  5790     Korea, N~    0.    0.    0.    0.    0.    0.    0.    0.    0. 0.       0.    0. 0.     0.   0.100  0.   0.    0.    0.     0.   0.    0.   
 2 1993  5790     Korea, N~    0.    0.    0.    0.    0.    0.    0.    0.    0. 0.       0.    0. 0.     0.   0.     0.   0.    0.    0.     0.   0.    0.   
 3 1994  5790     Korea, N~    0.    0.    0.    0.    0.    0.    0.    0.    0. 0.       0.    0. 0.     0.   0.     0.   0.    0.    0.200  0.   0.    0.   
 4 1995  5790     Korea, N~    0.    0.    0.    0.    0.    0.    0.    0.    0. 0.       0.    0. 0.     0.   0.     6.60 0.    0.    4.20   0.   0.    0.200
 5 1996  5790     Korea, N~    0.    0.    0.    0.    0.    0.    0.    0.    0. 0.       0.    0. 0.     0.   0.     0.   0.400 0.    0.     0.   0.    0.100
 6 1997  5790     Korea, N~    0.    0.    0.    0.    0.    0.    0.    0.    0. 0.       0.    0. 0.     0.   0.     0.   0.    0.100 0.     2.00 0.    0.300
 7 1998  5790     Korea, N~    0.    0.    0.    0.    0.    0.    0.    0.    0. 0.       0.    0. 0.     0.   0.     4.00 0.    0.    0.100  0.   0.300 0.   
 8 1999  5790     Korea, N~    0.    0.    0.    0.    0.    0.    0.    0.    0. 0.       0.    0. 0.     0.   0.100  0.   0.    0.300 0.     1.10 0.500 0.500
 9 2000  5790     Korea, N~    0.    0.    0.    0.    0.    0.    0.    0.    0. 0.100    0.    0. 0.100  2.50 0.100  0.   0.    0.    0.     0.   0.100 0.   
10 2001  5790     Korea, N~    0.    0.    0.    0.    0.    0.    0.    0.    0. 0.       0.    0. 0.     0.   0.     0.   0.    0.    0.     0.   0.    0.   
# ... with 16 more rows, and 4 more variables: EOCT <dbl>, ENOV <dbl>, EDEC <dbl>, EYR <dbl>

我第一次使用gather(),在导入月份工作,效果很好

USNKTrade <- USNKTrade %>% gather(contains("I"), key="month", value="ImportAmount")

导致

# A tibble: 338 x 18
   year  CTY_CODE CTYNAME       EJAN  EFEB  EMAR  EAPR  EMAY  EJUN  EJUL  EAUG  ESEP  EOCT  ENOV  EDEC    EYR month ImportAmount
   <chr> <chr>    <chr>        <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  <dbl> <chr>        <dbl>
 1 1992  5790     Korea, North  0.   0.100  0.   0.    0.    0.     0.   0.    0.    0.    0.    0.     0.100 IJAN            0.
 2 1993  5790     Korea, North  0.   0.     0.   0.    0.    0.     0.   0.    0.    0.    2.00  0.     2.00  IJAN            0.
 3 1994  5790     Korea, North  0.   0.     0.   0.    0.    0.200  0.   0.    0.    0.    0.    0.     0.200 IJAN            0.
 4 1995  5790     Korea, North  0.   0.     6.60 0.    0.    4.20   0.   0.    0.200 0.    0.500 0.100 11.6   IJAN            0.
 5 1996  5790     Korea, North  0.   0.     0.   0.400 0.    0.     0.   0.    0.100 0.    0.    0.     0.500 IJAN            0.
 6 1997  5790     Korea, North  0.   0.     0.   0.    0.100 0.     2.00 0.    0.300 0.    0.100 0.     2.50  IJAN            0.
 7 1998  5790     Korea, North  0.   0.     4.00 0.    0.    0.100  0.   0.300 0.    0.    0.    0.     4.40  IJAN            0.
 8 1999  5790     Korea, North  0.   0.100  0.   0.    0.300 0.     1.10 0.500 0.500 0.500 0.600 7.70  11.3   IJAN            0.
 9 2000  5790     Korea, North  2.50 0.100  0.   0.    0.    0.     0.   0.100 0.    0.    0.    0.     2.70  IJAN            0.
10 2001  5790     Korea, North  0.   0.     0.   0.    0.    0.     0.   0.    0.    0.    0.    0.500  0.500 IJAN            0.
# ... with 328 more rows

但是当我尝试对导出做同样的事情时,使用

USNKTrade <- USNKTrade %>% gather(starts_with("E"), key="month", value="ExportAmount")

然后我得到一个大约 4000 行长的 tibble,而实际上我想要一个只有前一个的两倍大的 tibble(这样每个导入和导出月份都有自己的行)。

我们将不胜感激!谢谢

【问题讨论】:

  • 请使用dput 展示一个可重现的小示例,并基于此显示预期输出
  • 我认为问题在于您已连续应用gather 命令。当您第一次在 contains("I") 列上应用 gather 时,这些列已移至行。现在在结果 data.frame 上,您正在应用 gatherstarts_with("E")。显然它会导致更多的行,因为带有I 列的行也会成倍增加。
  • 请注意,最好使用starts_with(),因为contains() 也会检测到不是首字母的EI
  • @hpesoj626 至少作为问题的一部分,OP 共享的任何列似乎与EI 没有冲突。也许 OP 明智地选择了 starts_with 来代替 E,否则会有重叠。

标签: r dplyr tidyr


【解决方案1】:

虽然OP 没有提供可重现的数据,但似乎问题在于OP 已在data.frame 上递归应用gather

 #The columns containing "I" will move to row after below command
 USNKTrade %>% gather(contains("I"), key="month", value="ImportAmount")

#Now below command will add for more rows
USNKTrade <- USNKTrade %>% gather(starts_with("E"), key="month", value="ExportAmount")

可行的解决方案可能是:

USNKTrade %>% select_at(vars(year, CTY_CODE, CTYNAME, contains("I"))) %>%
           gather(contains("I"), key="month", value="ImportAmount") %>%
inner_join(USNKTrade %>% select_at(vars(year, CTY_CODE, CTYNAME, starts_with("E"))) %>%
              starts_with(contains("E"), key="month", value="ImportAmount"),
         by = c("year", "CTY_CODE", "CTYNAME", "month"))

方法是首先只选择ImportAmount 所需的列,然后应用gather。现在只选择ExportAmount 所需的列,然后应用gather。合并两个集合。

假设"year", "CTY_CODE", "CTYNAME", "month" 将是key 列用于连接。

【讨论】:

    【解决方案2】:

    这是一种方法。使用starts_with() 而不是contains(),因为有些月份可能不仅在第一个字母中包含 E 或 I。在第二次收集中,请注意我已取消选择新创建的列 ImportAmountImportMonth 以及列 year

    year <- 1992:2001
    EJAN <- rnorm(10)
    IJAN <- rnorm(10)
    EFEB <- rnorm(10)
    IFEB <- rnorm(10)
    
    df <- data.frame(year, EJAN, IJAN, EFEB, IFEB)
    df %>% gather(starts_with("E"), key = ImportMonth, value = ImportAmount) %>%
      gather(starts_with("I"), key = ExportMonth, value = ExportAmount, -ImportAmount, -ImportMonth, - year)
    
    #    year ImportMonth ImportAmount ExportMonth ExportAmount
    # 1  1992        EJAN      -1.1528        IJAN      0.94967
    # 2  1993        EJAN       0.1165        IJAN      0.86506
    # 3  1994        EJAN       0.2553        IJAN     -0.05108
    # 4  1995        EJAN      -0.8516        IJAN     -0.50873
    # 5  1996        EJAN      -0.3014        IJAN      0.50614
    # 6  1997        EJAN       1.4017        IJAN      1.73527
    # 7  1998        EJAN       0.8019        IJAN     -0.71507
    # 8  1999        EJAN       1.7179        IJAN     -0.32709
    # 9  2000        EJAN      -1.2478        IJAN     -1.07364
    # 10 2001        EJAN      -1.0491        IJAN     -1.83764
    # ...
    # 40 2001        EFEB       1.2181        IFEB      0.76118
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-09
      • 2020-09-18
      • 2015-04-19
      • 1970-01-01
      相关资源
      最近更新 更多