【问题标题】:Extract strings from filename and create new columns using mutate从文件名中提取字符串并使用 mutate 创建新列
【发布时间】:2018-04-24 15:28:36
【问题描述】:

我有一个包含两列的 data.frame。第二列是文件名。

df  <- data.frame(paragraph = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
             filename = "./data/RevCon_2015_C1_Austria_05_06.txt", stringsAsFactors = FALSE)

如何从第二列中提取某些字符串(使用stringr)并将它们添加(使用dplyr::mutate)作为附加变量(会议、年份、国家等),以便得到以下结果:

df2  <- data.frame(paragraph = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
              filename = "./data/RevCon_2015_C1_Austria_05_06.txt", conference = "RevCon", year = "2015", country= "Austria", date = "06.05.2015", stringsAsFactors = FALSE)

【问题讨论】:

  • filename 列中的所有条目是否具有相同的模式? IE。 ./data/{conference}_{year}_{ignored}_{country}_{month}_{day}.txt?
  • 大部分,是的。有一些例外,但我想我可以过滤它们并在第二次运行中提取这些信息,然后加入两个数据集

标签: r stringr dplyr


【解决方案1】:

我们可以使用tidyr::separate

library(tidyverse);
df %>%
    mutate(tmp = gsub("(\\./data/|\\.txt)", "", filename)) %>%
    separate(
        tmp,
        into = c("conference", "year", "ignored", "country", "month", "day")) %>%
    mutate(date = paste(day, month, year, sep = "/")) %>%
    select(-ignored, -month, -day)
#          paragraph                                filename conference year
#1 Lorem ipsum [...] ./data/RevCon_2015_C1_Austria_05_06.txt     RevCon 2015
#  country        date
#1 Austria  06/05/2015

请注意,这假定 filenames 遵循以下模式:./data/{conference}_{year}_{ignored}_{country}_{month}_{day}.txt


样本数据

df  <- data.frame(
    paragraph = "Lorem ipsum [...]",
    filename = "./data/RevCon_2015_C1_Austria_05_06.txt",
    stringsAsFactors = FALSE)

【讨论】:

    【解决方案2】:

    这里有两种不同的方法,使用来自tidyrseparateextract

    library(dplyr)
    library(tidyr)
    
    df %>%
      mutate(filename2 = gsub("^(\\w+)_(\\d+)_.+?_(\\w+)_(\\d{2})_(\\d{2}).+$", 
                              "\\1_\\2_\\3_\\5.\\4.\\2", basename(filename))) %>%
      separate(filename2, c("conference", "year", "country", "date"), sep = "_")
    

    extract:

    df %>%
      extract(filename, c("conference", "year", "country", "day", "month"),
              "^.+/(\\w+)_(\\d+)_.+?_(\\w+)_(\\d{2})_(\\d{2}).+$",
              remove = FALSE) %>%
      unite(date, month, day, year, sep = ".", remove = FALSE) %>%
      select(paragraph, filename, conference, year, country, date)
    

    结果:

                                                                       paragraph
    1 Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.
                                     filename conference year country       date
    1 ./data/RevCon_2015_C1_Austria_05_06.txt     RevCon 2015 Austria 06.05.2015
    

    注意事项:

    1. 第一种方法使用gsub 来匹配我们想要使用捕获组的每个“列”,并根据需要重新排序。请注意,添加了_ 以区分列
      • 我使用basename 函数提取最后一个/ 之后的所有内容
      • 然后使用separate 将元素拆分为实际的列,_ 是分隔符
    2. 第二种方法使用相同的正则表达式,但不是重新排列,extract 将每个捕获组视为单独的列
      • unitemonthdayyear 绑定在一起,而不删除原始列
      • 最后select 删除daymonth 并重新排列列顺序

    【讨论】:

      猜你喜欢
      • 2023-01-21
      • 2017-06-18
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-01
      相关资源
      最近更新 更多