【问题标题】:Dplyr mutate duplicates list values when trying to index尝试索引时,Dplyr mutate 重复列表值
【发布时间】:2018-02-14 01:23:35
【问题描述】:

假设我从这样的数据集开始(它来自盖洛普)。我想将年份和日期从数据集中提取到新列中。所以我尝试拆分日期字符串...

index   date         R  D
1   2018 Jan 2-7    35  50  
2   2017 Dec 4-11   41  45  
3   2017 Nov 2-8    39  46  
4   2017 Oct 5-11   39  46  
5   2017 Sep 6-10   45  47  
6   2017 Aug 2-6    43  46

.. 使用变异

dataset <- data %>% 
      mutate(Y = strsplit(date, split = " ")[[1]][1]) %>%
      mutate(M = strsplit(date, split = " ")[[1]][2])

但 strsplit 似乎不是对日期行进行操作,而是对所有列值的列表进行操作。

所以我最终得到的 [[1]] 子集访问器只是获取第一行的值,而不是与每一行相关的列表条目。

index   date         R  D    Y        M
1   2018 Jan 2-7    35  3   2018    Jan
2   2017 Dec 4-11   41  3   2018    Jan
3   2017 Nov 2-8    39  3   2018    Jan
4   2017 Oct 5-11   39  3   2018    Jan
5   2017 Sep 6-10   45  3   2018    Jan
6   2017 Aug 2-6    43  3   2018    Jan

如何拆分字符串以便从列表中推断出每一行的值?使用索引作为子集访问器不起作用。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我建议使用包 stringr,它是 tidyverse 的一部分,因此可以与 dplyr 无缝协作。

    data %>% mutate(Y = str_extract(date, "^\\d{4}"),
                    M = str_extract(date, "[A-Za-z]{3}"))
    
    #   index          date  R  D    Y   M
    # 1     1  2018 Jan 2-7 35 50 2018 Jan
    # 2     2 2017 Dec 4-11 41 45 2017 Dec
    # 3     3  2017 Nov 2-8 39 46 2017 Nov
    # 4     4 2017 Oct 5-11 39 46 2017 Oct
    # 5     5 2017 Sep 6-10 45 47 2017 Sep
    # 6     6  2017 Aug 2-6 43 46 2017 Aug
    

    str_extract 允许您根据模式提取子字符串——在这里,我们使用两个不同的正则表达式。第一个匹配字符串开头的 4 个连续数字 (\\d{4}) (^)。第二个表达式只需 3 个连续的字母 ([A-Za-z]),考虑到您的日期结构,这是安全的。

    如果您仍想将strsplitmutate 一起使用,则可以添加对rowwise 的调用:

    data %>% rowwise() %>% mutate(Y = strsplit(date, split = " ")[[1]][1],
                                  M = strsplit(date, split = " ")[[1]][2])
    

    【讨论】:

    • 最终需要 rowwise(),使用了那个解决方案。
    【解决方案2】:

    我们可以将 中的extract 函数与捕获组一起使用。

    library(tidyr)
    
    dat2 <- dat %>%
      extract(date, into = c("Y", "M"), regex = "(\\d{4}) ([A-Za-z]{3})", remove = FALSE)
    dat2
    #   index          date    Y   M  R  D
    # 1     1  2018 Jan 2-7 2018 Jan 35 50
    # 2     2 2017 Dec 4-11 2017 Dec 41 45
    # 3     3  2017 Nov 2-8 2017 Nov 39 46
    # 4     4 2017 Oct 5-11 2017 Oct 39 46
    # 5     5 2017 Sep 6-10 2017 Sep 45 47
    # 6     6  2017 Aug 2-6 2017 Aug 43 46
    

    数据

    dat <- read.table(text = "index   date         R  D
    1   '2018 Jan 2-7'    35  50  
                      2   '2017 Dec 4-11'   41  45  
                      3   '2017 Nov 2-8'    39  46  
                      4   '2017 Oct 5-11'   39  46  
                      5   '2017 Sep 6-10'   45  47  
                      6   '2017 Aug 2-6'    43  46",
                      header = TRUE, stringsAsFactors = FALSE)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多