【问题标题】:Extracting values from a messy bulk of data从杂乱的大量数据中提取值
【发布时间】:2018-05-23 08:22:03
【问题描述】:

我有大量杂乱的数据,我想从中提取信息。现在,我还没有找到一种方便的方法来提取信息,希望您能提供帮助。我的数据如下所示:

"\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nChannels\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\
       n\r\nDates\r\nSeptember 25th 2016 To September 26th 
         2016\r\n\r\n\r\nPlatform\r\nIdea\r\n\r\n\r\nCountry\r\nUnited 
         States\r\n\r\n\r\nRestricted Countries\r\n\r\n\t\t\t\t\t\t\t\t\tUnited 
         States\t\t\t\t\t\t\t\t\r\n\r\n\r\nInitial Price\r\n$0.0692\r\n\r\n\r\n"

现在,我想摆脱的是:

Channels                - 
Dates                   September 25th 2016 To September 26th 2016
Platform                Idea
Country                 United States
Restricted Countries    United States
Initial Price           $0.0692

我需要对大量观察执行此任务,然后将每个变量存储为所有观察的向量。因此,我真的不需要存储变量的名称(即“平台”),而只需要存储结果(“想法”)。但要做到这一点,我需要“平台”变量名称作为“标识符”,我会假设,因为文本中变量的位置会随着观察值的变化而变化(变量的数量也是如此 - 只是略有不同)。

现在,我认为 stringr 包是一个很好的方法来做到这一点,但我还没有找到一个方便的方法来做到这一点。

【问题讨论】:

    标签: r regex string web-scraping stringr


    【解决方案1】:

    以下正则表达式提取您想要的值。这些值存储在结果矩阵的第 2-7 列中。该代码使用输入向量(每个条目在矩阵中形成一个新行)

    library(stringr)
    
    input <- "\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nChannels\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nDates\r\nSeptember 25th 2016 To September 26th 2016\r\n\r\n\r\nPlatform\r\nIdea\r\n\r\n\r\nCountry\r\nUnited States\r\n\r\n\r\nRestricted Countries\r\n\r\n\t\t\t\t\t\t\t\t\tUnited States\t\t\t\t\t\t\t\t\r\n\r\n\r\nInitial Price\r\n$0.0692\r\n\r\n\r\n"
    
    str_match(input, paste0("[[:space:]]*Channels[[:cntrl:]]+([[:print:]]+)?",
                            "[[:space:]]*Dates[[:cntrl:]]+([[:print:]]+)?",
                            "[[:space:]]*Platform[[:cntrl:]]+([[:print:]]+)?",
                            "[[:space:]]*Country[[:cntrl:]]+([[:print:]]+)?",
                            "[[:space:]]*Restricted Countries[[:cntrl:]]+([[:print:]]+)?",
                            "[[:space:]]*Initial Price[[:cntrl:]]+([[:print:]]+)?",
                            "[[:space:]]*"))
    

    编辑:对不起,我忽略了文本中变量的位置可以在不同的输入之间改变。在这种情况下,您无法使用此方法轻松地一次提取所有变量。但是,您仍然可以只使用上面正则表达式中的适当行来一一提取它们。如果不存在变量(例如您的示例中的“通道”),这不是问题 - 它将显示为 NA)。

    【讨论】:

    • 很高兴我能帮上忙 :) 请考虑将问题标记为此答案已回答。
    • :@AEF,完成!如果可以的话,一个后续问题:我已经确定了 1 个变量,我无法使用上面的代码进行提取。变量有一个?登录它,我认为是导致问题:nFunds in Escrow?\r\nNo\r\n\r\n\r\n\r\n\r\n 你有什么建议可以帮助吗?跨度>
    • 好吧,实际上您接受了另一个答案,但是好的,另一个似乎也可以;)关于问号:它是正则表达式中的特殊符号,需要转义。写吧 \\?代替 ?它应该可以工作。
    • 谢谢@AEF,它有效!抱歉,我不知道我只能选择 1 个答案,这个问题有多种解决方案。我重新选择了你的,因为这是我现在使用的。
    【解决方案2】:

    基础 R 解决方案:

    yourstring1 <- "\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\nChannels\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\
    n\r\nDates\r\nSeptember 25th 2016 To September 26th 
    2016\r\n\r\n\r\nPlatform\r\nIdea\r\n\r\n\r\nCountry\r\nUnited 
    States\r\n\r\n\r\nRestricted Countries\r\n\r\n\t\t\t\t\t\t\t\t\tUnited 
    States\t\t\t\t\t\t\t\t\r\n\r\n\r\nInitial Price\r\n$0.0692\r\n\r\n\r\n"
    
    # make a placeholder (useful when manipulating strings for easier regex)
    yourstring2 <- gsub("\r|\t|\nn|\n", "@", yourstring1, perl = T) # please note the double nn - this is so because a newline character is added when copying from here to R
    # split on placeholder if it appears twice or more
    yourstring2 <- unlist(strsplit(yourstring2, split = "@{2,}"))
    # little cleaning needed
    yourstring2 <- gsub(" @", " ", yourstring2)
    yourstring2[1:2] <- c(yourstring2[2], "-") # this hard-coded solution works for the particular example, if you have many strings with arbitrarily missing values, you may want to make a little condition for that
    # prepare your columns by indexing the character vector
    variables <- yourstring2[seq(from = 1, to = length(yourstring2), by = 2)]
    values <- yourstring2[seq(from = 2, to = length(yourstring2), by = 2)]
    # bind them to dataframe
    df <- data.frame(variables, values)
    

    结果df:

    df
                 variables                                     values
    1             Channels                                          -
    2                Dates September 25th 2016 To September 26th 2016
    3             Platform                                       Idea
    4              Country                              United States
    5 Restricted Countries                              United States
    6        Initial Price                                    $0.0692
    

    编辑:直到现在我才正确地阅读到,而不是数据框,所需的结果可能是位置向量......这是一个两行的解决方案

    yourstring2 <- gsub("\r|\t|\nn|\n", "", yourstring1, perl = T) #clean the original string (see above yourstring1)
    yourvector <- unlist(strsplit(yourstring2, split = "Channels|Dates|Platform|Country|Restricted Countries|Initial Price", perl = T))[-1]  # extract
    

    结果向量:

       > yourvector
    [1] ""                                          
    [2] "September 25th 2016 To September 26th 2016"
    [3] "Idea"                                      
    [4] "United States"                             
    [5] "United States"                             
    [6] "$0.0692"  
    

    【讨论】:

    • :@Radim:谢谢,它有效!我使用了上面 AEF 建议的 stringr 代码,因为它更容易循环,以便我可以检索所有观察的变量
    • 没问题,任何最适合您处理数据的方法,都很棒。我在思考如何在基本 R 中有效地做到这一点而没有太多正则表达式繁重的工作(它们在代码中很难阅读),我很开心。
    【解决方案3】:

    使用 a 作为输入字符串,结果将是一个数据框,每个关键字有一个变量(未使用的关键字缺少值),每个输入一行:

    a <- gsub("\\t*(\\r\\n)+\\t*","/",a)
    a <- gsub("(^/|/$)","",a)
    a <- gsub("(Channels|Dates|Platform|Country|Restricted Countries|Initial Price)","<\\1>",a)
    a <- gsub(">/<",">//<",a)
    b <- strsplit(a,"/")
    c <- purrr::map(b,
       function(x) {
            dim(x) <-  c(2,length(x)/2)
            tidyr::spread(as.data.frame(t(x),stringsAsFactors=FALSE),V1,V2)
        })
    replyr::replyr_bind_rows(c)
    

    【讨论】:

      猜你喜欢
      • 2022-11-19
      • 2019-10-20
      • 2019-08-22
      • 2017-10-10
      • 2016-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多