【问题标题】:Convert Comma-Separated Column to Columns with Booleans将逗号分隔的列转换为带布尔值的列
【发布时间】:2015-08-23 05:58:30
【问题描述】:

我的 data.frame 的一个名为 services 的列中有以下逗号分隔的数据。

> dput(structure(df$services[1:5]))
list("Global Expense Management, Company Privacy Policy", "Removal Services, Global Expense Management", 
    "Removal Services, Exception & Cost Admin, Global Cost Estimate, Company Privacy Policy", 
    "Removal Services, Exception & Cost Admin, Ancillary Services, Global Cost Estimate, Global Expense Management, Perm Storage, Company Privacy Policy", 
    "Global Expense Management, Company Privacy Policy")

我想将此数据转换为我的数据框中的单独列,如果该行包含服务,则在该服务的列下设置 TRUE。否则,将值设置为 FALSE。

例如,如果我希望我的数据框看起来像这样:

GlobalExpenseManagement    |    CompanyPrivacyPolicy   |   etc...
TRUE                            TRUE
TRUE                            FALSE
FALSE                           TRUE

我假设我必须拆分逗号分隔值,将它们分组以删除重复项,然后将它们作为 names(df) 添加到我的数据框中。但是,如果该行包含该服务,我不知道如何迭代数据集并设置真/假。

有没有人认为必须这样做的好主意?

编辑:合并数据

我现在正在尝试将新矩阵与我现有的数据框结合起来,以用新的列对应物替换服务。我已经根据@plafort 在下面的精彩回答进行了尝试:

names(df) <- headnames
rbind(mat, df)

但是,我收到此错误:

名称错误(df)

我也试过这个:

final <- data.frame(cbind(mat, df))

但是,它似乎缺少来自df 的列。如何合并从matdf 的列?

【问题讨论】:

    标签: r csv dataframe


    【解决方案1】:

    试试:

    splitup <- sapply(unlist(lst), strsplit, ', ')
    headnames <- unique(unlist(splitup))
    (mat <- t(unname(sapply(splitup, function(x) headnames %in% x))))
    
          [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]
    [1,]  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE
    [2,]  TRUE FALSE  TRUE FALSE FALSE FALSE FALSE
    [3,] FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE
    [4,]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
    [5,]  TRUE  TRUE FALSE FALSE FALSE FALSE FALSE
    

    我们首先用逗号分割数据,然后使用unlist 直接访问元素。 headnames 就像你提到的那样,寻找独特的类别标题。最后一行首先将标题类别与每个列表项匹配,然后使用unname 删除自动命名并将数据转换回我们希望使用t 的方式。

    为了在顶部添加名称,我们使用函数colnames 分配先前定义为列标题的唯一名称。该顺序正确运行,因为这是用于进行行观察的 headnames 向量。

    colnames(mat) <- headnames
    
    Global Expense Management Company Privacy Policy
    [1,]                      TRUE                   TRUE
    [2,]                      TRUE                  FALSE
    [3,]                     FALSE                   TRUE
    [4,]                      TRUE                   TRUE
    [5,]                      TRUE                   TRUE...
    

    【讨论】:

    • 看起来棒极了。无论如何要将这些列及其行附加到我现有data.frame的末尾? df[] &lt;- mat 会工作吗?我现在正在尝试这个,但我想我会问一下,以防我错了。
    • 你也许可以。列长度​​必须相同。此外,如果对象的类是混合的,则数据将被强制转换为字符。
    • 如果你使用函数调用df[] &lt;- mat,数据不会被追加,而是被覆盖。
    • 编辑:df[] &lt;- mat 无效。我只想将mat 中的所有列附加到df。行数应该已经匹配了。
    • 试试rbind(mat, df),但首先你必须将列名与names(df) &lt;- headnames匹配
    【解决方案2】:

    我会从我的“splitstackshape”包中考虑cSplit_e。结果是二进制的“1”和“0”,而不是TRUEFALSE,但这应该很容易转换。

    样本数据:

    df <- data.frame(services = I(
      list("Global Expense Management, Company Privacy Policy", "Removal Services, Global Expense Management", 
           "Removal Services, Exception &amp; Cost Admin, Global Cost Estimate, Company Privacy Policy", 
           "Removal Services, Exception &amp; Cost Admin, Ancillary Services, Global Cost Estimate, Global Expense Management, Perm Storage, Company Privacy Policy", 
           "Global Expense Management, Company Privacy Policy")))
    

    将“服务”列转换为vector 而不是list

    df$services <- unlist(df$services)
    

    现在拆分一下:

    library(splitstackshape)
    cSplit_e(df, "services", ",", type = "character", fill = 0)
    ##                                                                                                                                                  services
    ## 1                                                                                                       Global Expense Management, Company Privacy Policy
    ## 2                                                                                                             Removal Services, Global Expense Management
    ## 3                                                              Removal Services, Exception &amp; Cost Admin, Global Cost Estimate, Company Privacy Policy
    ## 4 Removal Services, Exception &amp; Cost Admin, Ancillary Services, Global Cost Estimate, Global Expense Management, Perm Storage, Company Privacy Policy
    ## 5                                                                                                       Global Expense Management, Company Privacy Policy
    ##   services_Ancillary Services services_Company Privacy Policy services_Exception &amp; Cost Admin
    ## 1                           0                               1                                   0
    ## 2                           0                               0                                   0
    ## 3                           0                               1                                   1
    ## 4                           1                               1                                   1
    ## 5                           0                               1                                   0
    ##   services_Global Cost Estimate services_Global Expense Management services_Perm Storage
    ## 1                             0                                  1                     0
    ## 2                             0                                  1                     0
    ## 3                             1                                  0                     0
    ## 4                             1                                  1                     1
    ## 5                             0                                  1                     0
    ##   services_Removal Services
    ## 1                         0
    ## 2                         1
    ## 3                         1
    ## 4                         1
    ## 5                         0
    

    【讨论】:

    • 这看起来很棒,我尝试使用cSplit,但不知道cSplit_e。问题是,我的 CSV 数据中有特殊字符,所以它给了我Error: unexpected symbol in "df &lt;- cSplit_e(df, 'services', ',' type"。我正在使用正则表达式来删除除字母、空格和逗号之外的所有内容...
    • 我删除了特殊字符,但它仍然给我错误。我就是这样做的:cleanServiceNames &lt;- function(x) gsub('[^A-Za-z,]', '', x)df$services &lt;- lapply(df$services, cleanServiceNames)。有什么想法吗?
    • @user1477388,您能否使用dput 在一个可重现的小示例中隔离问题?如果可以的话,我也许可以提供帮助,但除此之外,排除故障有点困难。
    • 这就是问题所在。我上面已经有dput(structure(db$services[1:5])),但我不知道导致错误的“特殊字符”在哪里。我认为从我的正则表达式中,除了逗号和字母之外的所有内容都应该被删除。所以,除了整个数据集很大之外,我不知道该给你什么来重现。
    • @user1477388,我不知道该推荐什么。您能否检查数据集并查看是否有任何可能导致问题的可疑行?如果是这样,请尝试使用dput
    猜你喜欢
    • 2012-12-02
    • 2020-04-07
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 2021-10-21
    • 1970-01-01
    相关资源
    最近更新 更多