【问题标题】:How to group files in a list based on name?如何根据名称对列表中的文件进行分组?
【发布时间】:2021-07-21 11:37:06
【问题描述】:

我有 4 个文件:

MCD18A1.A2001001.h15v05.061.2020097222704.hdf

MCD18A1.A2001001.h16v05.061.2020097221515.hdf

MCD18A1.A2001002.h15v05.061.2020079205554.hdf

MCD18A1.A2001002.h16v05.061.2020079205717.hdf

我想在一个列表中按名称(日期:A2001001 和 A2001002)对它们进行分组,如下所示:

[[MCD18A1.A2001001.h15v05.061.2020097222704.hdf, MCD18A1.A2001001.h16v05.061.2020097221515.hdf], [MCD18A1.A2001002.h15v05.061.2020079205554.hdf, MCD18A1.A2001002.h16v05.061.2020079205717.hdf]]

我是用 Python 做的,但我不知道如何用 R:

# Seperate files by date
MODIS_files_bydate = [list(i) for _, i in itertools.groupby(MODIS_files, lambda x: x.split('.')[1])]

【问题讨论】:

    标签: r group-by split filenames itertools


    【解决方案1】:

    这是你要找的吗?

    g <- sub("^[^\\.]*\\.([^\\.]+)\\..*$", "\\1", s)
    split(s, g)
    #$A2001001
    #[1] "MCD18A1.A2001001.h15v05.061.2020097222704.hdf"
    #[2] "MCD18A1.A2001001.h16v05.061.2020097221515.hdf"
    #
    #$A2001002
    #[1] "MCD18A1.A2001002.h15v05.061.2020079205554.hdf"
    #[2] "MCD18A1.A2001002.h16v05.061.2020079205717.hdf"
    

    正则表达式解释

    正则表达式分为三个部分。

    1. ^[^\\.]*\\.
      • ^第一个抑扬符标志着字符串的开始;
      • ^[^\\.] 开头,一个否定点的类(第二个^)。点是元字符,因此必须转义,\\.
      • 开头没有点的序列重复零次或多次 (*);
      • 前面的序列以点结束,\\.
    2. ([^\\.]+) 是一个捕获组。
      • [^\\.]没有点的类,如上;
      • [^\\.]+ 至少重复了一次 (+)。
    3. \\..*$"
      • \\. 以一个点开头
      • \\..*$ 任何字符重复零次或多次直到结束 ($)。

    sub 替换的是捕获组,括号之间的内容本身就是\\1。这会丢弃其他所有内容。


    数据

    s <- "
    MCD18A1.A2001001.h15v05.061.2020097222704.hdf
    MCD18A1.A2001001.h16v05.061.2020097221515.hdf
    MCD18A1.A2001002.h15v05.061.2020079205554.hdf
    MCD18A1.A2001002.h16v05.061.2020079205717.hdf"
    s <- scan(text = s, what = character())
    

    【讨论】:

    • 这项工作!但是由于正则表达式,我不太了解 g ,您能解释一下 sub 正在替换什么吗?谢谢
    • @Just_4n0th3r_Pr0gr4mm3r 添加了解释。立即查看。
    【解决方案2】:

    您希望结果如何组织?

    这是一个解决方案:

    files <- c("MCD18A1.A2001001.h15v05.061.2020097222704.hdf",
               
               "MCD18A1.A2001001.h16v05.061.2020097221515.hdf",
               
               "MCD18A1.A2001002.h15v05.061.2020079205554.hdf",
               
               "MCD18A1.A2001002.h16v05.061.2020079205717.hdf")
    
    unique_date <- unique(sub("^[^\\.]*\\.([^\\.]+)\\..*$", "\\1", files))
    # (credit to Rui Barradas for the nice regular expression)
    
    grouped_files <- lapply(unique_date, function(x){files[grepl(x, files)]})
    
    names(grouped_files) <- unique_date
    
    > grouped_files
    # $A2001001
    # [1] "MCD18A1.A2001001.h15v05.061.2020097222704.hdf"  "MCD18A1.A2001001.h16v05.061.2020097221515.hdf"
    
    # $A2001002
    # [1] "MCD18A1.A2001002.h15v05.061.2020079205554.hdf"  "MCD18A1.A2001002.h16v05.061.2020079205717.hdf"
    

    【讨论】:

    • 为什么要应用独特的功能?你能解释一下正在取代什么?谢谢
    • 这样每个日期都会有一个“组”。然后为每个组找到所有相关日期。 sub() 只是挑选日期的一种方法:第一个参数是模式(前两个点之间的内容),第二个参数引用该模式并且是替换。每个文件名都被替换为找到的模式。
    猜你喜欢
    • 1970-01-01
    • 2022-08-19
    • 1970-01-01
    • 2014-05-18
    • 2019-11-08
    • 1970-01-01
    • 2017-06-18
    • 1970-01-01
    • 2016-01-30
    相关资源
    最近更新 更多