【问题标题】:Extract and match sets from list of filenames从文件名列表中提取和匹配集
【发布时间】:2020-03-01 23:56:57
【问题描述】:

我有一个包含 4000 多张图像的数据集。为了弄清楚代码,我将其中的一小部分移到了另一个文件夹中。

文件如下所示:

文件夹

[1] "r01c01f01p01-ch3.tiff" "r01c01f01p01-ch4.tiff" "r01c01f02p01-ch1.tiff"
[4] "r01c01f03p01-ch2.tiff" "r01c01f03p01-ch3.tiff" "r01c01f04p01-ch2.tiff"
[7] "r01c01f04p01-ch4.tiff" "r01c01f05p01-ch1.tiff" "r01c01f05p01-ch2.tiff"
[10] "r01c01f06p01-ch2.tiff" "r01c01f06p01-ch4.tiff" "r01c01f09p01-ch3.tiff"
[13] "r01c01f09p01-ch4.tiff" "r01c01f10p01-ch1.tiff" "r01c01f10p01-ch4.tiff"
[16] "r01c01f11p01-ch1.tiff" "r01c01f11p01-ch2.tiff" "r01c01f11p01-ch3.tiff"
[19] "r01c01f11p01-ch4.tiff" "r01c02f10p01-ch1.tiff" "r01c02f10p01-ch2.tiff"
[22] "r01c02f10p01-ch3.tiff" "r01c02f10p01-ch4.tiff"

我无法删除 -ch# 之前的名称,因为该信息很重要。然而,我想要做的是过滤这个图像列表,并只返回具有所有四个 ch 值(ch1-4)的集合(即:r01c02f10p01)。

我原本以为我们可以这样处理这个问题:

ch1 <- dir(path="/Desktop/cp/complete//", pattern="ch1")
ch2 <- dir(path="/Desktop/cp/complete//", pattern="ch2")
ch3 <- dir(path="/Desktop/cp/complete//", pattern="ch3")
ch4 <- dir(path="/Desktop/cp/complete//", pattern="ch4")

使用file.remove 函数应用此列表,类似于:

final2 <- dir(path="/Desktop/cp1/Images//", pattern="ch5") 
file.remove(folder,final2) 

但是,为每个 ch 值创建新变量会分散每个文件。我不确定如何使用这些来实际区分单个图像是否具有所有四个 ch 值来有意义地过滤我的图像。我有点不知所措,因为我看到的其他来源的问题与这个问题不太匹配。

之前,我可以像这样从我的图像集中删除所有带有 ch5 的图像。我在想这可能有助于尝试仅过滤具有 ch1-ch4 的图像,但我不确定如何继续。

##Create folder variable which has all image files 
folder <- list.files(getwd())

##Create final2 variable which has all image files ending in ch5
final2 <- dir(path="/Desktop/cp1/Images//", pattern="ch5") 

##Remove final2 from folder
file.remove(folder,final2) 

总结一下:我希望从没有完整 ch 值(即:可能只有 ch1 和 ch2,或 ch3 和 ch4,或 ch1、ch2、ch3 和 ch4)的随机分类中过滤文件,到只包含具有完整集合的文件(四个文件,分别为 ch1、ch2、ch3 和 ch4)。

【问题讨论】:

    标签: r sorting filtering


    【解决方案1】:

    从一个文件名向量开始,就像你从list.files 或类似的东西得到的,你可以创建一个文件名数据框,使用正则表达式提取开头的字母数字部分和"-ch" 后面的数字。然后检查预期集合的所有元素(我将其放在ch_set 中,但您可能需要另一种方式来执行此操作)出现在每个组的 CH 值集合中。

    # assume this is the vector of file names that comes from list.files
    # or something comparable
    files <- c("r01c01f01p01-ch3.tiff", "r01c01f01p01-ch4.tiff", "r01c01f02p01-ch1.tiff", "r01c01f03p01-ch2.tiff", "r01c01f03p01-ch3.tiff", "r01c01f04p01-ch2.tiff", "r01c01f04p01-ch4.tiff", "r01c01f05p01-ch1.tiff", "r01c01f05p01-ch2.tiff", "r01c01f06p01-ch2.tiff", "r01c01f06p01-ch4.tiff", "r01c01f09p01-ch3.tiff", "r01c01f09p01-ch4.tiff", "r01c01f10p01-ch1.tiff", "r01c01f10p01-ch4.tiff", "r01c01f11p01-ch1.tiff", "r01c01f11p01-ch2.tiff", "r01c01f11p01-ch3.tiff", "r01c01f11p01-ch4.tiff", "r01c02f10p01-ch1.tiff", "r01c02f10p01-ch2.tiff", "r01c02f10p01-ch3.tiff", "r01c02f10p01-ch4.tiff")
    
    library(dplyr)
    
    ch_set <- 1:4
    
    files_to_keep <- data.frame(filename = files, stringsAsFactors = FALSE) %>%
      tidyr::extract(filename, into = c("group", "ch"), regex = "(^[\\w\\d]+)\\-ch(\\d)", remove = FALSE) %>%
      mutate(ch = as.numeric(ch)) %>%
      group_by(group) %>% 
      filter(all(ch_set %in% ch))
    
    files_to_keep
    #> # A tibble: 8 x 3
    #> # Groups:   group [2]
    #>   filename              group           ch
    #>   <chr>                 <chr>        <dbl>
    #> 1 r01c01f11p01-ch1.tiff r01c01f11p01     1
    #> 2 r01c01f11p01-ch2.tiff r01c01f11p01     2
    #> 3 r01c01f11p01-ch3.tiff r01c01f11p01     3
    #> 4 r01c01f11p01-ch4.tiff r01c01f11p01     4
    #> 5 r01c02f10p01-ch1.tiff r01c02f10p01     1
    #> 6 r01c02f10p01-ch2.tiff r01c02f10p01     2
    #> 7 r01c02f10p01-ch3.tiff r01c02f10p01     3
    #> 8 r01c02f10p01-ch4.tiff r01c02f10p01     4
    

    现在您有了完整组的数据框,只需将匹配的文件名拉回即可:

    files_to_keep$filename
    #> [1] "r01c01f11p01-ch1.tiff" "r01c01f11p01-ch2.tiff" "r01c01f11p01-ch3.tiff"
    #> [4] "r01c01f11p01-ch4.tiff" "r01c02f10p01-ch1.tiff" "r01c02f10p01-ch2.tiff"
    #> [7] "r01c02f10p01-ch3.tiff" "r01c02f10p01-ch4.tiff"
    

    需要注意的一点是,在没有 mutate 行的情况下,我将 ch 转换为数字 - 即将这些数字的字符版本与它们的常规数字版本进行比较——因为在后台,%in% 转换为匹配类型。如果您需要对其进行扩展,这似乎并不完全安全,因此我将它们转换为匹配类型。

    【讨论】:

    • 如果我想将其扩展到 4000 多个图像,我将很难像您在第一步中那样创建文件列表。难道我们不能通过使用一个名为“文件夹”的变量来实现同样的效果吗?还是错过了变量类型之间的转换以在其余代码中使用它们?
    • 如果您的意思是变量files,我必须这样做,因为您没有包含您正在使用的文件名的可行示例。我通过清理您包含的打印输出文本制作了矢量。看起来你通过调用list.files 得到了类似的东西,但是由于无法访问你的文件列表,我以这种方式模仿它。将其替换为您正在获取的文件列表。
    • 使用 list.files 命令正是我首先让一切正常工作的方式,我想我跟着你。我现在遇到的问题实际上是观察代码应该编写的更改。我的原始文件夹没有反映更改,当我尝试 final
    • 不工作怎么办?你的意思是原始文件夹没有反映更改?我没有包括对实际文件的任何操作,因为您的问题是关于找出合适的文件是什么
    • @Wysteria 进行批量文件创建/删除/移动似乎与仅提取和计算部分文件名不同的任务。也许将其作为一个单独的问题发布
    猜你喜欢
    • 1970-01-01
    • 2014-09-11
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 2019-12-21
    • 2014-01-20
    • 2013-11-06
    • 2019-11-05
    相关资源
    最近更新 更多