【问题标题】:Extract variables with specific names and loop for all files提取具有特定名称的变量并为所有文件循环
【发布时间】:2021-05-26 05:52:38
【问题描述】:

目的是 (1) 提取具有特定名称的变量(列) (2) 循环文件夹中的所有文件以及 (3) 将输出保存在 csv 文件中。

例如,一个文件的数据看起来像:

structure(list(frame = c(1, 2, 3, 4, 5), g_1 = c(0.1, 0.2, 0.1, 
0, 0), g_2 = c(0, 0, 0, 0, 0), xy_1 = c(0.4, 0.43, 0.32, 0.33, 
0.39), xy_2 = c(0, 0, 0, 0, 0.1), unit_1 = c(1, 1, 1, 1, 1), 
    unit_2 = c(0, 0, 0, 0, 0), unit_3 = c(0, 0, 0, 0, 0)), class = "data.frame", row.names = c(NA, 
-5L), variable.labels = structure(character(0), .Names = character(0)), codepage = 65001L)

对于每个数据集,我只需要变量 (1) 框架和 (2) 以“unit_”开头的变量。所以我需要为每个文件获取并保存在 csv 中的输出如下所示:

╔═══════╦════════╦════════╦════════╗
║ frame ║ unit_1 ║ unit_2 ║ unit_3 ║
╠═══════╬════════╬════════╬════════╣
║  1.00 ║  1.00  ║   .00  ║   .00  ║
╠═══════╬════════╬════════╬════════╣
║  2.00 ║  1.00  ║   .00  ║   .00  ║
╠═══════╬════════╬════════╬════════╣
║  3.00 ║  1.00  ║   .00  ║   .00  ║
╠═══════╬════════╬════════╬════════╣
║  4.00 ║  1.00  ║   .00  ║   .00  ║
╠═══════╬════════╬════════╬════════╣
║  5.00 ║  1.00  ║   .00  ║   .00  ║
╚═══════╩════════╩════════╩════════╝

我想知道是否有办法使用 dplyr 或其他方法来做到这一点。

我在想:

files <- list.files(path="C:/files", pattern="csv")
out <- lapply(files, function(file) {
  dat <- data.frame(fread(paste0("C:/files/", file) ) ) 
  dat <- dat[c("frame", "unit_1", "unit_2", "unit_3")]})

从这里开始,我不清楚如何将每个文件保存到 csv 文件中。

【问题讨论】:

    标签: r dplyr data.table tidyr


    【解决方案1】:

    我们将selectselect_helpers 一起使用,例如starts_with

    library(dplyr)
    df1 %>% 
         select(frame, starts_with('unit'))
    

    -输出

    #   frame unit_1 unit_2 unit_3
    #1     1      1      0      0
    #2     2      1      0      0
    #3     3      1      0      0
    #4     4      1      0      0
    #5     5      1      0      0
    

    matches 中的正则表达式以匹配以子字符串“unit”开头 (^) 后跟 _ 和一个或多个数字 (\\d+) 结尾 ($) 的模式) 作为列名的字符串

    df1 %>%
          select(frame, matches('^unit_\\d+$'))
    

    如果它是data.frame的list,用map/walk循环遍历list,用read_csv读取文件,选择感兴趣的列并在同一目录中创建带有前缀'的新文件new_' 使用write_csv

    library(purrr)
    library(readr)
    library(stringr)
    walk(files, ~ read_csv(file.path("C:/files", .x)) %>%
                   select(frame, starts_with('unit')) %>%
                   write_csv(file.path("C:/files", str_c("new_", .x)))
           )
    

    base R 中的等效选项是 startsWith

    subset(df1, select = c('frame',
              names(df1)[startsWith(names(df1), 'unit')]))
    

    grep

    subset(df1, select = grep('^(frame|unit)', names(df1), value = TRUE))
    

    对于 list 的文件

    lapply(files, function(x) {
          tmp <-  subset(read.csv(file.path("C:/files", x)),
                  select = grep('^(frame|unit)', names(df1), value = TRUE))
        write.csv(tmp, file.path("C:/files", paste0("new_", x)), 
                     row.names = FALSE, quote = FALSE)
        })
    

    【讨论】:

    • 谢谢@akrun 我会合并你的 dplyr 代码;你能看看我写的最后一行代码吗?我想知道将存储在“out”中的每个文件保存在csv中的好方法是什么。
    • @user14250906 需要保存为新文件还是更新的旧文件
    • 对,作为新文件!顺便说一句,你的代码真的很棒;这应该是更多人应该知道的!
    • @user14250906 将代码更新为walk 请检查
    • 哇,使用 walk 非常高效。谢谢你..!
    猜你喜欢
    • 2012-07-19
    • 2014-04-26
    • 2013-01-08
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    • 2014-02-25
    相关资源
    最近更新 更多