【问题标题】:trasforming text into matrix to become .csv in R将文本转换为矩阵以成为 R 中的 .csv
【发布时间】:2014-08-06 22:38:07
【问题描述】:

我有以下文字:

Anada - Asociación de nada Address: calle 13 13 Medellin Colombia Other
address: Phone.: 13-13-136131 13-13-13-1313 E-mail: anada@13.co Web page: Category: 3. Private sector Notes:
Atodo - Asociación de todo Address: calle 12 Bogota Colombia
Other address: Phone.: 12-1-23-32  E-mail: Web page: www.atodoooo.com, Category: 99. Public sector Notes: note that there are missing fields.

我想获得一个矩阵,其列名要转换为 .csv 文件:

Company, Address, Other Address, Tel, E-mail, Web page, Category, Sector, Notes

和行:

Anada - Asociación de nada, calle 13 13 Medellin Colombia, 13-13-136131 13-13-13-1313,anada@13.co,,3,Private,,

Atodo - Asociación de todo,calle 12 Bogota Colombia,,12-1-23-32,www.atodoooo.com,99,Public,note that there are missing fields.

用 R 怎么做?

【问题讨论】:

    标签: r export-to-csv strsplit


    【解决方案1】:

    这可能很乏味,但似乎需要字符串处理。

    splitlist = 'Address|Other address|Phone|E-mail|Web page|Category'  
    a = str_split(text[1], ':')  
    
    for (i in 1:length(a[[1]])) {  
     a[[1]][i] = str_replace_all(a[[1]][i], splitlist, "")  
    }  
    
    # [[1]]
    # [1] "Atodo - Asociacin de todo "           " calle 12 Bogota Colombia "          
    # [3] " ."                                   " 12-1-23-32  "                       
    # [5] " "                                    " www.atodoooo.com, "                 
    # [7] " 99. Public sector Notes"             " note that there are missing fields."
    

    然后你可以用更少的字符串处理来提取每个字段。

    在这种情况下,除了正则表达式之外,我想不出任何更简单的方法。

    【讨论】:

    • Thnaks,但它并不能解决我的多个案例问题。
    • 什么可以解决我的问题(除了第一项),是 text
    【解决方案2】:

    以下假设您的记录在每个条目上一行,也就是说,它看起来像:

    text <- c("Anada - Asociación de nada Address: calle 13 13 Medellin Colombia Other address: Phone.: 13-13-136131 13-13-13-1313 E-mail: anada@13.co Web page: Category: 3. Private sector Notes:", 
              "Atodo - Asociación de todo Address: calle 12 Bogota Colombia Other address: Phone.: 12-1-23-32  E-mail: Web page: www.atodoooo.com, Category: 99. Public sector Notes: note that there are missing fields.")
    

    如果不是,但如果我们可以假设“Address:”字段总是在第一行,我们可以这样做:

    ## Starting point
    text <- c("Anada - Asociación de nada Address: calle 13 13 Medellin Colombia Other", 
              "address: Phone.: 13-13-136131 13-13-13-1313 E-mail: anada@13.co Web page: Category: 3. Private sector Notes:", 
              "Atodo - Asociación de todo Address: calle 12 Bogota Colombia", 
              "Other address: Phone.: 12-1-23-32  E-mail: Web page: www.atodoooo.com, Category: 99. Public sector Notes: note that there are missing fields.")
    
    ## Locate the elements that have "Address:" and use cumsum to get an index
    ## Use tapply to paste the relevant vector elements together into single strings
    text <- tapply(text, 
                   cumsum(grepl("Address:", text)), 
                   paste, collapse = " ")
    

    从那里,方法基本上如下:

    • 提取“标题”部分的list
    • 提取相关值的list
    • 将它们重新组合成一个向量。
    • 再次拆分它们。
    • 将结果从“长”格式重塑为“宽”格式。

    使用的工具如下:

    library(devtools)
    library(data.table)
    library(reshape2)
    source_gist("11380733") ## For cSplit
    

    方法开始类似于@won782。

    splitlist <- c("Address:", "Other address:", "Phone.:", "E-mail:", "Web page:",
                   "Category:", "Public sector Notes:", "Private sector Notes:")
    pattern <- paste0(splitlist, collapse = "|")
    

    我发现一些“stringr”函数有点慢,所以坚持使用base R:

    X1 <- regmatches(text, gregexpr(pattern, text))
    X2 <- regmatches(text, gregexpr(pattern, text), invert = TRUE)
    
    Combined <- Map(paste0, 
                    lapply(X1, append, values = "Company:", after = 0), 
                    lapply(X2, data.table:::trim))
    

    这是我们目前所处的位置:

    Combined
    # [[1]]
    # [1] "Company:Anada - Asociación de nada"    "Address:calle 13 13 Medellin Colombia"
    # [3] "Other address:"                        "Phone.:13-13-136131 13-13-13-1313"    
    # [5] "E-mail:anada@13.co"                    "Web page:"                            
    # [7] "Category:3."                           "Private sector Notes:"                
    # 
    # [[2]]
    # [1] "Company:Atodo - Asociación de todo"                     
    # [2] "Address:calle 12 Bogota Colombia"                       
    # [3] "Other address:"                                         
    # [4] "Phone.:12-1-23-32"                                      
    # [5] "E-mail:"                                                
    # [6] "Web page:www.atodoooo.com,"                             
    # [7] "Category:99."                                           
    # [8] "Public sector Notes:note that there are missing fields."
    

    cSplit 函数可以很好地与data.tables 配合使用,所以让我们直接使用它吧。

    DT <- data.table(V1 = unlist(Combined))       ## unlist the values
    DT <- cSplit(DT, "V1", ":")                   ## Split by a colon
    DT[, V1_1 := gsub("Public sector |Private sector ", "", V1_1)]  ## Just "notes"
    DT[, id := cumsum(V1_1 == "Company")]         ## Add an id column
    

    从那里,我们可以使用dcast.data.table 将数据集从“长”数据集转换为“宽”数据集,如下所示:

    dcast.data.table(DT, id ~ V1_1, value.var = "V1_2")
    #    id                       Address Category                    Company
    # 1:  1 calle 13 13 Medellin Colombia       3. Anada - Asociación de nada
    # 2:  2      calle 12 Bogota Colombia      99. Atodo - Asociación de todo
    #         E-mail                               Notes Other address
    # 1: anada@13.co                                  NA            NA
    # 2:          NA note that there are missing fields.            NA
    #                        Phone.          Web page
    # 1: 13-13-136131 13-13-13-1313                NA
    # 2:                 12-1-23-32 www.atodoooo.com,
    

    【讨论】:

    • 谢谢,但假设每个条目只有一行是不正确的。上面的示例包含两个条目,但它们没有分行。
    • 无格式文本中的所有条目,但是应该很容易将文本转换为每个条目一行。哪种方法最简单?
    • @xav,“地址:”是否可能始终位于条目的第一行?如果是这样,那么它应该很容易解决。
    • 我看到你转换的文本已经被分割了。以下是应有的文字:
    • c("Anada - Asociación de nada 地址: calle 13 13 Medellin Colombia 其他地址: Phone.: 13-13-136131 13-13-13-1313 E-mail: anada@13.co网页: 类别: 3. 私营部门 备注: Atodo - Asociación de todo 地址: calle 12 Bogota Colombia 其他地址: 电话: 12-1-23-32 电子邮件: 网页: www.atodoooo.com,类别: 99. 公共部门注意事项:请注意缺少字段。”)
    猜你喜欢
    • 2017-08-24
    • 2018-06-05
    • 2017-09-16
    • 2015-10-28
    • 1970-01-01
    • 2017-03-22
    • 2016-09-28
    • 2013-02-12
    • 1970-01-01
    相关资源
    最近更新 更多