【问题标题】:indented unordered list to nested list()缩进无序列表到嵌套列表()
【发布时间】:2017-12-10 03:50:24
【问题描述】:

我有一个如下所示的日志文件:

Data:
 +datadir=/data/2017-11-22
 +Nusers=5292
Parameters:
 +outdir=/data/2017-11-22/out
 +K=20
 +IC=179
 +ICgroups=3
   -group 1: 1-1
    ICeffects: 1-5
   -group 2: 2-173
    ICeffects: 6-10
   -group 3: 175-179
    ICeffects: 11-15

我想使用 R 将此日志文件解析为嵌套列表,以便结果如下所示:

result <- list(Data = list(datadir = '/data/2017-11-22',
                           Nusers = 5292),
               Parameters = list(outdir = '/data/2017-11-22/out',
                                 K = 20,
                                 IC = 179,
                                 ICgroups = list(list('group 1' = '1-1',
                                                      ICeffects = '1-5'),
                                                      list('group 2' = '2-173',
                                                      ICeffects = '6-10'),
                                                      list('group 1' = '175-179',
                                                      ICeffects = '11-15'))))

有没有一种不是非常痛苦的方法?

【问题讨论】:

    标签: r list parsing


    【解决方案1】:

    免责声明:这很混乱。无法保证这将适用于更大/不同的文件而无需进行一些调整。您需要仔细检查。

    这里的关键思想是重新格式化原始数据,使其与 YAML 格式一致,然后使用yaml::yaml.load 解析数据以生成嵌套列表。

    顺便说一句,这是一个很好的例子,说明了为什么人们真的应该为日志输出/配置文件(如 JSON、YAML 等)使用通用标记语言...

    我假设您使用readLines 读取日志文件以生成字符串向量ss

    # Sample data
    ss <- c(
        "Data:",
        " +datadir=/data/2017-11-22",
        " +Nusers=5292",
        "Parameters:",
        " +outdir=/data/2017-11-22/out",
        " +K=20",
        " +IC=179",
        " +ICgroups=3",
        "   -group 1: 1-1",
        "    ICeffects: 1-5",
        "   -group 2: 2-173",
        "    ICeffects: 6-10",
        "   -group 3: 175-179",
        "    ICeffects: 11-15")
    

    然后我们重新格式化数据以符合 YAML 格式。

    # Reformat to adhere to YAML formatting
    ss <- gsub("\\+", "- ", ss);                   # Replace "+" with "- "
    ss <- gsub("ICgroups=\\d+","ICgroups:", ss);   # Replace "ICgroups=3" with "ICgroups:"
    ss <- gsub("=", " : ", ss);                    # Replace "=" with ": "
    ss <- gsub("-group", "- group", ss);           # Replace "-group" with "- group"
    ss <- gsub("ICeffects", " ICeffects", ss);     # Replace "ICeffects" with " ICeffects"
    

    请注意 - 与您的预期输出一致 - 来自 ICgroups 的值 3 不会被使用,我们需要将 ICgroups=3 替换为 ICgroups: 以启动嵌套子列表。这是首先让我失望的部分......

    加载和解析 YAML 字符串然后生成一个嵌套列表。

    require(yaml);
    lst <- yaml.load(paste(ss, collapse = "\n"));
    lst;
    
    #$Data
    #$Data[[1]]
    #$Data[[1]]$datadir
    #[1] "/data/2017-11-22"
    #
    #
    #$Data[[2]]
    #$Data[[2]]$Nusers
    #[1] 5292
    #
    #
    #
    #$Parameters
    #$Parameters[[1]]
    #$Parameters[[1]]$outdir
    #[1] "/data/2017-11-22/out"
    #
    #
    #$Parameters[[2]]
    #$Parameters[[2]]$K
    #[1] 20
    #
    #
    #$Parameters[[3]]
    #$Parameters[[3]]$IC
    #[1] 179
    #
    #
    #$Parameters[[4]]
    #$Parameters[[4]]$ICgroups
    #$Parameters[[4]]$ICgroups[[1]]
    #$Parameters[[4]]$ICgroups[[1]]$`group 1`
    #[1] "1-1"
    #
    #$Parameters[[4]]$ICgroups[[1]]$ICeffects
    #[1] "1-5"
    #
    #
    #$Parameters[[4]]$ICgroups[[2]]
    #$Parameters[[4]]$ICgroups[[2]]$`group 2`
    #[1] "2-173"
    #
    #$Parameters[[4]]$ICgroups[[2]]$ICeffects
    #[1] "6-10"
    #
    #
    #$Parameters[[4]]$ICgroups[[3]]
    #$Parameters[[4]]$ICgroups[[3]]$`group 3`
    #[1] "175-179"
    #
    #$Parameters[[4]]$ICgroups[[3]]$ICeffects
    #[1] "11-15"
    

    PS。您需要在较大的文件上对此进行测试,并在必要时对替换进行更改。

    【讨论】:

    • 聪明!是的,我仍然对ICgroups 感到困惑,所以如果你有一个简单的解决方案,那将不胜感激
    • @RoyalTS 我现在可以解析您提供的完整示例数据,请查看我更新的解决方案。这很可能需要对更大/不同的日志文件进行一些调整,但这是我能想到的最好的。另一种方法是编写自己的解析器...
    猜你喜欢
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 2010-09-21
    • 2012-01-07
    • 2013-02-06
    相关资源
    最近更新 更多