【问题标题】:Data frame R - lookup for the part of the string and return certain two values数据框 R - 查找字符串的一部分并返回某些两个值
【发布时间】:2020-01-02 12:31:52
【问题描述】:

我有一个带有 xml 导出的数据框,我想查找 ceratin 字符串并从中返回两个值。下面是我的数据样本的代码。

a <- c(
  '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><businessObjectChanges version="1"><table><datetime>1500977276442</datetime><name>XX_header</name><row><datetime>1500977276442</datetime><transactionType>UPDATE</transactionType><column><name>est_groundtime</name><newValue>420</newValue><oldValue>480</oldValue><mimeType>TIME</mimeType></column><column><name>start_time</name><newValue>540</newValue><oldValue>480</oldValue><mimeType>TIME</mimeType></column><column><name>XXno_i</name><primaryKey>true</primaryKey><newValue>11</newValue><oldValue>11</oldValue></column></row></table></businessObjectChanges>',
   '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><businessObjectChanges version="1"><table><datetime>1500977363880</datetime><name>XX_header</name><row><datetime>1500977363880</datetime><transactionType>UPDATE</transactionType><column><name>end_time</name><newValue>922</newValue><oldValue>960</oldValue><mimeType>TIME</mimeType></column><column><name>XXno_i</name><primaryKey>true</primaryKey><newValue>11</newValue><oldValue>11</oldValue></column></row></table></businessObjectChanges>',
    '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><businessObjectChanges version="1"><table><datetime>1500977598476</datetime><name>XX_header</name><row><datetime>1500977598476</datetime><transactionType>UPDATE</transactionType><column><name>act_start_date</name><newValue>16642</newValue><oldValue>null</oldValue><mimeType>DATE</mimeType></column><column><name>act_start_time</name><newValue>607</newValue><oldValue>0</oldValue><mimeType>TIME</mimeType></column><column><name>act_end_date</name><newValue>16642</newValue><oldValue>null</oldValue><mimeType>DATE</mimeType></column><column><name>act_end_time</name><newValue>667</newValue><oldValue>0</oldValue><mimeType>TIME</mimeType></column><column><name>delay</name><newValue>7</newValue><oldValue>0</oldValue><mimeType>TIME</mimeType></column><column><name>XXno_i</name><primaryKey>true</primaryKey><newValue>205</newValue><oldValue>205</oldValue></column></row></table></businessObjectChanges>',
    '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><businessObjectChanges version="1"><table><datetime>1500977613945</datetime><name>XX_header</name><row><datetime>1500977613945</datetime><transactionType>UPDATE</transactionType><column><name>XX_status</name><newValue>-2</newValue><oldValue>18</oldValue><mimeType>INT</mimeType></column><column><name>XXno_i</name><primaryKey>true</primaryKey><newValue>205</newValue><oldValue>205</oldValue></column></row></table></businessObjectChanges>',
    '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><businessObjectChanges version="1"><table><datetime>1500977892448</datetime><name>XX_header</name><row><datetime>1500977892448</datetime><transactionType>UPDATE</transactionType><column><name>XX_status</name><newValue>19</newValue><oldValue>-2</oldValue><mimeType>INT</mimeType></column><column><name>XXno_i</name><primaryKey>true</primaryKey><newValue>29</newValue><oldValue>29</oldValue></column></row></table></businessObjectChanges>',
    '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><businessObjectChanges version="1"><table><datetime>1500977738390</datetime><name>XX_header</name><row><datetime>1500977738390</datetime><transactionType>UPDATE</transactionType><column><name>act_start_date</name><newValue>16641</newValue><oldValue>null</oldValue><mimeType>DATE</mimeType></column><column><name>act_start_time</name><newValue>367</newValue><oldValue>0</oldValue><mimeType>TIME</mimeType></column><column><name>act_end_date</name><newValue>16641</newValue><oldValue>null</oldValue><mimeType>DATE</mimeType></column><column><name>act_end_time</name><newValue>667</newValue><oldValue>0</oldValue><mimeType>TIME</mimeType></column><column><name>XXno_i</name><primaryKey>true</primaryKey><newValue>44</newValue><oldValue>44</oldValue></column></row></table></businessObjectChanges>',
    '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><businessObjectChanges version="1"><table><datetime>1500977757374</datetime><name>XX_header</name><row><datetime>1500977757374</datetime><transactionType>UPDATE</transactionType><column><name>XX_status</name><newValue>19</newValue><oldValue>18</oldValue><mimeType>INT</mimeType></column><column><name>XXno_i</name><primaryKey>true</primaryKey><newValue>44</newValue><oldValue>44</oldValue></column></row></table></businessObjectChanges>',
    '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><businessObjectChanges version="1"><table><datetime>1500977836229</datetime><name>XX_header</name><row><datetime>1500977836229</datetime><transactionType>UPDATE</transactionType><column><name>act_start_date</name><newValue>16640</newValue><oldValue>null</oldValue><mimeType>DATE</mimeType></column><column><name>act_start_time</name><newValue>96</newValue><oldValue>0</oldValue><mimeType>TIME</mimeType></column><column><name>act_end_date</name><newValue>16640</newValue><oldValue>null</oldValue><mimeType>DATE</mimeType></column><column><name>act_end_time</name><newValue>156</newValue><oldValue>0</oldValue><mimeType>TIME</mimeType></column><column><name>XXno_i</name><primaryKey>true</primaryKey><newValue>203</newValue><oldValue>203</oldValue></column></row></table></businessObjectChanges>'

)

a <- as.data.frame(a)

我的数据框“a”需要两列。第一个是基于关注XX_status,第二个是再次关注XX_status。

所以,第 1 到第 3 行不包含 XX_status 所以对他们来说任何东西,第 4 行有它与下面的摘录,它将是 -2 和 18,对于第 5 行,它将是 18 和 2 等等...

任何想法将不胜感激

【问题讨论】:

    标签: r regex string


    【解决方案1】:

    这是处理这种情况的一种方法。我尝试先使用stri_extract_all_regex() 提取长字符串的特定部分。然后,我进一步尝试在第二个stri_extract_all_regex() 中提取数字。然后,我使用unnest_wider() 创建了两列,最后为数据框分配了列名。我希望这会对你有所帮助。

    library(tidyverse)
    library(stringi)
    
    transmute(a,
              res = stri_extract_all_regex(str = a,
                                           pattern = "XX_status</name><newValue>-?\\d+</newValue><oldValue>-?\\d+</oldValue>") %>% 
                    stri_extract_all_regex(pattern = "(?<=>)-?\\d+(?=<)")) %>% 
    unnest_wider(res) %>% 
    setNames(nm = c("new_value", "old_value"))
    
    #  new_value old_value
    #  <chr>     <chr>    
    #1 NA        NA       
    #2 NA        NA       
    #3 NA        NA       
    #4 -2        18       
    #5 19        -2       
    #6 NA        NA       
    #7 19        18       
    #8 NA        NA  
    

    【讨论】:

    • 只有一个问题 - 当我尝试将结果作为新的 df 获取时,它会打印所有带有以下文本的行:'New names: * `` -> ...1' 知道如何不打印或如何将“new_value”和“old_value”作为列添加到a?
    • @Kalenji 当你给我发短信时,我睡着了。您可能有多个列,对吧?在这种情况下,你想做这样的事情:paste(rep(c("new_value", "old_value"), times = 2), rep(1:2, each = 2), sep = "_")。你想在setNames() 中有这个。第一个rep() 中的times 表示您有多少对。在第二个rep() 中,将1:2 更改为1:n。 n 等于times 中的数字。通过这种方式,您可以创建您需要的所有列名。
    【解决方案2】:

    我们可以使用stringr包和REGEX来提取这些值,如下所示。

    library(dplyr)
    library(stringr)
    
    a <- c(...) # your XML string here
    
    a <- as.data.frame(a)
    
    a <-  a 
    %>% mutate(
    status = str_extract(a, "XX_status[\\<\\/.\\>\\w\\d\\-]+\\<\\/oldValue\\>\\ 
    <mimeType\\>"),
    newValue = str_extract(status, "newValue\\>[\\-]*\\d+"),
    newValue = as.numeric(str_extract(newValue, "[\\-]*\\d+")),
    oldValue = str_extract(status, "oldValue\\>[\\-]*\\d+"),
    oldValue = as.numeric(str_extract(oldValue, "[\\-]*\\d+"))) 
    %>% select(-status)
    

    【讨论】:

    • 好的。我需要做一些改变。这是一个很棒的代码。
    猜你喜欢
    • 2020-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 2018-08-29
    • 1970-01-01
    • 2018-12-11
    • 1970-01-01
    相关资源
    最近更新 更多