【问题标题】:Repeat the same operations in multiple files in R在 R 中的多个文件中重复相同的操作
【发布时间】:2021-08-09 15:27:56
【问题描述】:

我想在具有相同格式 [1:1259] 的多个文件中重复相同的操作。每个文件都有一个列名Image,我想在其中提取一个数字并用它创建另一个列。

我想对每个文件重复的代码。

r<- regexpr("\\d+", Seg_grow_1mm.csv[,"Image"])
Seg_grow_1mm_01<- Seg_grow_1mm.csv %>%
  mutate(., new_id=(regmatches(Seg_grow_1mm.csv[,"Image"], r)))

Seg_grow_1mm_01 预览

#   ID    Image                                                                    New_id
#   02     /Users/LLG/Data avec smoothing-margin/CHUM/05/Augmentation 3 mm/           05
#   03     /Users/LLG/Data avec smoothing-margin/CHUM/103/Augmentation 3 mm/          103
#   04     /Users/LLG/Data avec smoothing-margin/CHUM/145/Augmentation 3 mm/          145
# ....

我想对我的每个文件重复此操作。我尝试了一个循环但没有成功,我不知道如何将它转换为一个函数,以便我可以在我的文件列表中使用 lapply。

seg = list.files(path=csv, pattern="*.csv") # Seg[1:3]

for (i in 1:length(seg))
  assign(seg[i], read.csv(seg[i]))for (x in seg)
      r<- regexpr("\\d+", x[,"Image"])
      mutate(., new_id=(regmatches( x[,"Image"], r)))

Error in x[, "Image"] : incorrect number of dimensions

我不知道该放什么??

seg01<- lapply(seg, function (z)
  {r<- regexpr("\\d+", ?? [,"Image"])
  mutate(., new_id=(regmatches( ?? [,"Image"], r)))})

感谢您的帮助!

【问题讨论】:

  • stackoverflow.com/a/24376207/3358227 是关于使用列表框架/表格的一个很好的讨论。
  • @r2evans,谢谢你的链接,但它对我的问题没有帮助......
  • 好的,很抱歉。如果不知道数据是什么样子,我不确定我还能提出什么建议。您不必展示所有 1000 多列来展示您需要的内容。我不确定这是否是关于如何使用lapply、如何处理多个文件或如何从字符串中提取数字(正则表达式或其他)的问题。
  • 抱歉,如果不清楚……英语不是我的母语,我还是 R 新手。我创建了我的文件的一个小预览(dput(head(de) 太可怕了……)我的问题真的是关于如何对我的列表段的每个文件执行正则表达式。我可以为每个文件单独执行此操作。现在,我有 3 个文件,因此很容易将代码复制过去 3 次,即使它不是高效,但很快我的列表段中就会有 15 个 csv 文件。
  • 因此,您有一个类似于Seg_grow_1mm_01 的文件列表。这些文件共享相同的结构(作为 data.frame),如预览中所示。现在您想提取image 列中的数字(在您的示例中为05103145)并将它们放入每个data.frame 的新列中?

标签: r for-loop lapply


【解决方案1】:

您可以使用tidyverse 方法:

seg <- list.files(pattern="*.csv")

library(purrr)
library(readr)
library(dplyr)
library(stringr)

seg %>% 
  map(read_csv) %>% 
  map(~ .x %>% 
        mutate(new_id = str_extract(Image, "(?<=/)\\d+(?=/)"))) %>% 
  `names<-`(.,seg)

创建一个命名的 data.frames/tibbles 列表

$example1.csv
# A tibble: 3 x 3
  ID    Image                                                             new_id
  <chr> <chr>                                                             <chr> 
1 02    /Users/LLG/Data avec smoothing-margin/CHUM/05/Augmentation 3 mm/  05    
2 03    /Users/LLG/Data avec smoothing-margin/CHUM/103/Augmentation 3 mm/ 103   
3 04    /Users/LLG/Data avec smoothing-margin/CHUM/145/Augmentation 3 mm/ 145   

$example2.csv
# A tibble: 3 x 3
     ID Image                                           new_id   
  <dbl> <chr>                                           <chr>    
1    23 /example/directory/1983/Augmentation 3 mm/      1983     
2    42 /example/directory/105123/Augmentation 3 mm/    105123   
3    99 /example/directory/151252145/Augmentation 3 mm/ 151252145

基于我的两个示例文件。使用assign,您可以在您的全球环境中创建data.frames,但这不是必需的。

如果你想把这个列表写回单独的.csv-files,你可以使用

seg %>% 
  map(read_csv) %>% 
  map(~ .x %>% 
        mutate(new_id = str_extract(Image, "(?<=/)\\d+(?=/)"))) %>% 
  `names<-`(.,seg) %>%
  map2(.x = .,
       .y = paste("new_", seg),
       ~ write_csv(x = .x, file = .y))

这会在您当前的工作目录中创建带有前缀new_ 和旧文件名的文件。如果您想要像“oldfilename_01.csv”这样的文件名,只需将paste("new_", seg) 替换为str_replace(seg, "\\.csv", "_01\\.csv")

【讨论】:

  • 嗨@Martin Gal,感谢您的回答。我不明白如何阅读每个单独的文件?以及如何为列表的每个元素编写一个 csv?
  • 您的代码使用了list.files() 函数。此函数创建一个文件名向量。我们使用这个列表,将.csv-files 读入data.frames 列表(即map(read_csv)-part)。也许您必须首先将工作目录设置为包含.csv-files 的目录。您可以使用setwd("PATHtoYOURfiles") 进行操作。
  • @TchatCusson 我编辑了我的答案以澄清它。希望这会有所帮助。
  • 在哪里可以找到有关 map() 的更多有用信息?
  • 这是一个好的开始:rebeccabarter.com/blog/2019-08-19_purrr
猜你喜欢
  • 2017-06-30
  • 1970-01-01
  • 2019-04-05
  • 1970-01-01
  • 2021-07-25
  • 2016-06-29
  • 1970-01-01
  • 2020-07-23
  • 1970-01-01
相关资源
最近更新 更多