【问题标题】:Split uneven strings into sorted columns in R将不均匀的字符串拆分为R中的排序列
【发布时间】:2019-06-27 14:12:29
【问题描述】:

进行了一项调查,其中一个问题可以选择多个答案。选择多个答案时,它们都记录在同一个单元格中。

此外,每个测量员在单元格中记录此信息的方式也不同。有时分隔符是连字符 (-),有时是正斜杠 (/)。还有一些测量员用数字列出了这些项目。

一个例子是房子里的物品清单(见下图/图片)。我想在每个项目可用时创建列(新列可以有 1/0 或项目名称/NA)(见下面的结果示例)。

我可以使用文本到列和查找数组在 excel 中执行此操作,但是有很多具有同一列的 excel 表,我必须在 R 中执行此操作。抱歉,我不知道如何制作使用 R 代码的示例表,但希望有人能够提供帮助。

这是数据的样子:

House = c("h1","h2","h3","h4","h5","h6","h7","h8","h9","h10","h11")
Items = c("Chair", "Chair- Window/Glass- "," Door- Sofa-", "Chair- 
Window/Glass Frame- ", "1. Window/Glass Frame", "Chair- Door- Window-", "Chair- Sofa - Door- Table-", " 4. Table", "Couch (2)", "Window- Table- Chair- Sofa- Door- Couach", "2. Door / Chair")
table1 = as.data.table(House)
table2 = as.data.table(Items)
table = as.data.frame(append(table1, table2))

table

+-------+------------------------------------------+
| House |                  Items                   |
+-------+------------------------------------------+
|   001 | Chair                                    |
|   002 | Chair- Window/Glass-                     |
|   003 | Door- Sofa-                              |
|   004 | Chair- Window/Glass Frame-               |
|   005 | 1. Window/Glass Frame                    |
|   006 | Chair- Door- Window-                     |
|   007 | Chair- Sofa - Door- Table-               |
|   008 | 4. Table                                 |
|   009 | Couch (2)                                |
|   010 | Window- Table- Chair- Sofa- Door- Couach |
|   011 | 2. Door / Chair                          |
+-------+------------------------------------------+

我的想法是使用所有分隔符(strsplit)进行拆分,删​​除空格(trimws),获取唯一列表(唯一),然后用我想要的标准替换所有变体(grepl),最后根据类别。

items <- strsplit(df$Items, "[/.-]")
items <- trimws(items)
items <- df$Items %>%
    strsplit("[/.-]") %>%
    str_trim(side = "both")
items_list <- unique(items)

这就是我想要得到的: (窗户和玻璃是一样的,椅子/沙发/沙发是一样的,等等——所以我只需要创建更大的类别,而不是有几列基本相同的东西)

Outcome

+-------+-------+--------+-------+------+
| House | Chair | Window | Table | Door |
+-------+-------+--------+-------+------+
|   001 | Chair |        |       |      |
|   002 | Chair | Window |       |      |
|   003 | Chair |        |       | Door |
|   004 | Chair | Window |       |      |
|   005 |       | Window |       |      |
|   006 | Chair | Window |       | Door |
|   007 | Chair |        | Table | Door |
|   008 |       |        | Table |      |
|   009 | Chair |        |       |      |
|   010 | Chair | Window | Table | Door |
|   011 | Chair |        |       | Door |
+-------+-------+--------+-------+------+

【问题讨论】:

  • 你能把输入例子的dput贴出来
  • 刚刚编辑了带有输出@akrun 的问题。谢谢!
  • 请使用 dput 而不是这个格式
  • 自我推销:阅读this这种格式可能会有所帮助。
  • @akrun -- 我无法制作 dput() 但我制作了其他东西,可以在 R 中为您提供一个表格(在问题中编辑)。我希望现在我能得到一些帮助!谢谢!

标签: r sorting unique strsplit grepl


【解决方案1】:

您可以在map_df(或sapply)中使用str_detect(或grepl)生成逻辑数据帧,将其强制为整数0/1,然后将其绑定到您的原始数据帧。这种方法绕过了拆分/清理/等的麻烦。数据。它只要求您首先为您的正则表达式创建模式组,即chair|sofa|couach|couchwindow|glass

library(stringr)
library(dplyr)
library(purrr)

# Create regex pattern groups.
patts <- c(chair = "chair|sofa|couach|couch", window = "window|glass", 
           table = "table", door = "door")

# Detect pattern groups, coerce to 0/1, bind to origional dataframe.
map_df(patts, ~ str_detect(df$Items, regex(., ignore_case = T))) %>%
    mutate_all(as.integer) %>% 
    bind_cols(df, .)

这将返回以下数据框:

# A tibble: 11 x 6
   House Items                                    chair window table  door
   <dbl> <chr>                                    <int>  <int> <int> <int>
 1     1 Chair                                        1      0     0     0
 2     2 "Chair- Window/Glass- "                      1      1     0     0
 3     3 " Door- Sofa-"                               1      0     0     1
 4     4 "Chair- Window/Glass Frame- "                1      1     0     0
 5     5 1. Window/Glass Frame                        0      1     0     0
 6     6 Chair- Door- Window-                         1      1     0     1
 7     7 Chair- Sofa - Door- Table-                   1      0     1     1
 8     8 " 4. Table"                                  0      0     1     0
 9     9 Couch (2)                                    1      0     0     0
10    10 Window- Table- Chair- Sofa- Door- Couach     1      1     1     1
11    11 2. Door / Chair                              1      0     0     1 

数据:

df <- tibble(House = c(1,2,3,4,5,6,7,8,9,10,11), Items = c("Chair", "Chair- Window/Glass- "," Door- Sofa-", "Chair- Window/Glass Frame- ", "1. Window/Glass Frame", "Chair- Door- Window-", "Chair- Sofa - Door- Table-", " 4. Table", "Couch (2)", "Window- Table- Chair- Sofa- Door- Couach", "2. Door / Chair"))

【讨论】:

  • 这是一个很好的解决方案,也是解决问题的好方法!完美运行 - 感谢@gersht!只是出于好奇(并且要了解更多信息),而不是 0/1,是否有一种简单的方法可以让列/类别名称代替 1 并在 0 中为空(如我的输出示例)?如果这太复杂了也没关系,因为这是完美的!
  • @kt2630 很高兴听到它有帮助!要使用这些名称,只需将 mutate_all(as.integer) 替换为 map2_df(names(.), ~ ifelse(.x, .y, ""))。请注意,这不是最有用的数据格式。使用 TRUE/FALSE 更容易,或者对于某些应用程序可能使用 1/0。如果您只需要名称用于显示目的,那当然可以。
猜你喜欢
  • 2014-02-16
  • 2016-06-16
  • 2021-12-23
  • 2019-07-23
  • 2021-06-24
  • 2023-04-02
  • 2017-01-09
  • 1970-01-01
相关资源
最近更新 更多