【问题标题】:Creating columns from unorganized data based on substrings基于子字符串从无组织的数据创建列
【发布时间】:2018-06-10 16:32:50
【问题描述】:

我的论文数据遇到了以下问题。在第一列“id”之后,我有一个带有水平无组织字符串单元的数据框。我想在行内组织字符串,以便以相同的前 4 个字符开头的所有字符串都保留在同一列中。

由于相关类别数量有限(少于 20 个),我可以手动执行此操作,首先是“Arra”,然后是“Comm”等等。我用grepl 尝试了这个,但未能返回原始的单元格字符串。我只得到 TRUE/FALSE。非常感谢您的帮助!

我当前的数据如下所示。 (我将 NA 单元格留空)

id  col2              col3               col4         col5
3   Commitment 100    Lead Mgmt 15      Arranger 50
8   Arrangement 20    Front-end 80
16  Lead mgmt 40      Commitmnt 20
17
20  Arranger 50     

它应该是这样的:

id  Arra           Comm            Fron         Lead
3   Arranger 50    Commitment 100               Lead Mgmt 15
8   Arrangement 20                 Front-end 80
16                 Commitmnt 20                 Lead mgmt 40
17
20  Arranger 50

【问题讨论】:

  • 请使用dput()分享您的数据摘录

标签: r sorting substring reshape grepl


【解决方案1】:

这是一种可能的方法:

library(data.table)
dcast(melt(as.data.table(mydf), "id", na.rm = TRUE)[value != ""][
  , ind := substr(value, 1, 4)], id ~ ind, value.var = "value", fill = "")
#    id           Arra           Comm         Fron         Lead
# 1:  3    Arranger 50 Commitment 100              Lead Mgmt 15
# 2:  8 Arrangement 20                Front-end 80             
# 3: 16                  Commitmnt 20              Lead mgmt 40
# 4: 20    Arranger 50   

并且,以类似的逻辑,在“tidyverse”中:

library(tidyverse)
mydf[is.na(mydf)] <- ""
mydf %>%
  gather(var, val, starts_with("col")) %>%
  filter(val != "") %>%
  mutate(ind = substr(val, 1, 4)) %>%
  select(-var) %>%
  spread(ind, val)
#   id           Arra           Comm         Fron         Lead
# 1  3    Arranger 50 Commitment 100         <NA> Lead Mgmt 15
# 2  8 Arrangement 20           <NA> Front-end 80         <NA>
# 3 16           <NA>   Commitmnt 20         <NA> Lead mgmt 40
# 4 20    Arranger 50           <NA>         <NA>         <NA>

样本数据:

mydf <- structure(list(id = c(3L, 8L, 16L, 17L, 20L), col2 = c("Commitment 100", 
    "Arrangement 20", "Lead mgmt 40", "", "Arranger 50"), col3 = c("Lead Mgmt 15", 
    "Front-end 80", "Commitmnt 20", "", ""), col4 = c("Arranger 50", 
    "", "", "", ""), col5 = c(NA, NA, NA, NA, NA)), .Names = c("id", 
    "col2", "col3", "col4", "col5"), row.names = c(NA, 5L), class = "data.frame")

如果您的原始数据中有重复的存根,例如,如果第 1 行中的“col5”有另一个“承诺”值:

mydf$col5[1] <- "Commitment 99"

你可以试试这样的:

dcast(melt(as.data.table(mydf), "id", na.rm = TRUE)[value != ""][
  , ind := substr(value, 1, 4)], 
  id ~ ind + rowid(id, ind), value.var = "value", fill = "")
#    id         Arra_1         Comm_1        Comm_2       Fron_1       Lead_1
# 1:  3    Arranger 50 Commitment 100 Commitment 99              Lead Mgmt 15
# 2:  8 Arrangement 20                              Front-end 80             
# 3: 16                  Commitmnt 20                            Lead mgmt 40
# 4: 20    Arranger 50                                                       

或者这个:

dcast(melt(as.data.table(mydf), "id", na.rm = TRUE)[value != ""][
  , ind := substr(value, 1, 4)], 
  id ~ ind, value.var = "value", fun = function(x) x[1], fill = "")
#    id           Arra           Comm         Fron         Lead
# 1:  3    Arranger 50 Commitment 100              Lead Mgmt 15
# 2:  8 Arrangement 20                Front-end 80             
# 3: 16                  Commitmnt 20              Lead mgmt 40
# 4: 20    Arranger 50                                         

取决于您想要的输出。

【讨论】:

  • 非常感谢您的回答。到目前为止,我设法只获得了每种变量类型的数量(就像在您的示例中一样,但是在“Arra”列中有“1”而不是“Arranger 50”)。我认为这是因为在某些行中存在例如多个承诺或前端值。您是否知道任何简单的解决方案,例如忽略多个值?目前我正在努力删除这些行并将回复您。顺便说一句,我尝试按照您的建议为您获取样本数据,但我没有设法使用 dput() 从 R 中提取比整个数据更小的样本。我不知道为什么。
  • @PauliLohi,您需要决定是要删除还是要添加指标变量以允许多个。
  • 如果有机会允许多个,那就太好了。
  • @PauliLohi,我希望您有机会在我的回答末尾看到这两种选择。第一个选项允许多个。第二个选项只是提取第一个值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-24
  • 2022-06-17
  • 2019-06-05
  • 2020-12-03
  • 1970-01-01
  • 2018-05-23
  • 2016-02-13
相关资源
最近更新 更多