Разбить неровные строки на отсортированные столбцы в R - PullRequest
3 голосов
/ 27 июня 2019

Был проведен опрос, и на один из вопросов была возможность выбрать несколько ответов.При выборе нескольких ответов все они были записаны в одной и той же ячейке.

Кроме того, способ, которым эта информация была записана в ячейке, был различным для каждого геодезиста.Иногда разделителем был дефис (-), а иногда - косая черта (/).Также некоторые геодезисты перечислили пункты с номерами.

Примером является список предметов в доме (см. Ниже / изображение).Я хотел бы создать столбцы, когда каждый элемент доступен (новые столбцы могут иметь либо 1/0, либо имя элемента / NA) (см. Пример результата ниже).

Я мог бы сделать это в Excel, используя text-to-column и lookup массивы, но существует столько таблиц 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))

таблица

+-------+------------------------------------------+
| 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)

Вот то, что я пытаюсь получить: (окно и стекло одинаковы, стул / диван / диван одинаковы и т. Д., Поэтому мне просто нужно создать более крупные категории вместо нескольких столбцовтакой же тонкийг)

Исход

+-------+-------+--------+-------+------+
| 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 |
+-------+-------+--------+-------+------+

1 Ответ

2 голосов
/ 27 июня 2019

Вы можете использовать str_detect (или grepl) в map_df (или sapply), чтобы сгенерировать логический кадр данных, привести их к целым числам 0/1, а затем привязать его к исходному информационному кадру. Этот метод обходит проблемы разделения / очистки / и т. Д. данные. Это просто требует, чтобы вы сначала создали группы шаблонов для своего регулярного выражения, то есть chair|sofa|couach|couch, window|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"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...