Несколько категориальных переменных в столбце и подготовка - PullRequest
2 голосов
/ 16 февраля 2020

У меня есть данные опроса, с текстовыми ответами, категориальными переменными и цифрами c.

Преобразованы в фрейм данных в pandas, но проблема в столбцах с множественным выбором, иногда их больше, чем 1 категориальные переменные, поскольку опрос был задуман как «выберите все подходящие варианты».

Например:

ID  Category    Num1 Num2 Num3
1   A, B, C     1    1    1
2   B, C, D     1    0    1
3   A, C        1    1    1
4   A           0    1    1
5   A, C, D     0    1    1

Я пытаюсь сопоставить эти категории с числовыми переменными.

Скажем, присутствие A для значения Num1.

Но когда я использую фрейм данных, как он есть, Python (и R) рассматривает, например, [A, B, C] как другое category, распознает всю ячейку как категорию.

Я думаю, что мне нужен метод синтаксического анализа (взрыва?) значения (скрытым образом) перед подачей в команду статистического анализа.

Как я могу решить эту проблему?

Ответы [ 3 ]

1 голос
/ 16 февраля 2020

Мы можем использовать cSplit_e из splitstackshape в R

library(splitstackshape)
cSplit_e(df1, "Category", type =  "character", fill = 0, sep=",\\s*", fixed = FALSE)
#   ID Category Num1 Num2 Num3 Category_A Category_B Category_C Category_D
#1  1  A, B, C    1    1    1          1          1          1          0
#2  2  B, C, D    1    0    1          0          1          1          1
#3  3     A, C    1    1    1          1          0          1          0
#4  4        A    0    1    1          1          0          0          0
#5  5  A, C, D    0    1    1          1          0          1          1

В base R мы можем разделить столбец «Категория» на , и затем использовать table

cbind(df1, as.data.frame.matrix(table(stack(setNames(strsplit(df1$Category,
             ",\\s+"), df1$ID))[2:1])))
#   ID Category Num1 Num2 Num3 A B C D
#1  1  A, B, C    1    1    1 1 1 1 0
#2  2  B, C, D    1    0    1 0 1 1 1
#3  3     A, C    1    1    1 1 0 1 0
#4  4        A    0    1    1 1 0 0 0
#5  5  A, C, D    0    1    1 1 0 1 1

Можно сделать еще более компактным с

library(qdapTools)
cbind(df1, mtabulate(strsplit(df1$Category, ",\\s+")))
#  ID Category Num1 Num2 Num3 A B C D
#1  1  A, B, C    1    1    1 1 1 1 0
#2  2  B, C, D    1    0    1 0 1 1 1
#3  3     A, C    1    1    1 1 0 1 0
#4  4        A    0    1    1 1 0 0 0
#5  5  A, C, D    0    1    1 1 0 1 1

data

df1 <- structure(list(ID = 1:5, Category = c("A, B, C", "B, C, D", "A, C", 
"A", "A, C, D"), Num1 = c(1L, 1L, 1L, 0L, 0L), Num2 = c(1L, 0L, 
1L, 1L, 1L), Num3 = c(1L, 1L, 1L, 1L, 1L)), class = "data.frame", row.names = c(NA, 
-5L))
0 голосов
/ 16 февраля 2020

Если вы готовы использовать tidyverse (или tidyr плюс dplyr), я думаю, вы могли бы использовать separate_rows. Это разделит ваши категории, а затем вы можете использовать pivot_wider, чтобы создать дополнительные столбцы для этих категорий.

library(tidyverse)

df %>%
  separate_rows(Category, sep = ",") %>%
  mutate(temp = TRUE) %>%
  pivot_wider(names_from = Category, values_from = temp, values_fill = list(temp = FALSE))

Выход

# A tibble: 5 x 8
     ID  Num1  Num2  Num3 A     B     C     D    
  <int> <int> <int> <int> <lgl> <lgl> <lgl> <lgl>
1     1     1     1     1 TRUE  TRUE  TRUE  FALSE
2     2     1     0     1 FALSE TRUE  TRUE  TRUE 
3     3     1     1     1 TRUE  FALSE TRUE  FALSE
4     4     0     1     1 TRUE  FALSE FALSE FALSE
5     5     0     1     1 TRUE  FALSE TRUE  TRUE 
0 голосов
/ 16 февраля 2020

Если ваш фрейм данных называется df, то вы можете проверить наличие «A» в Category, например:

grepl("A", as.character(df$Category))
#> [1]  TRUE FALSE  TRUE  TRUE  TRUE

Если вы хотите, чтобы TRUE и FALSE были равны 1 и 0, вы просто сделайте:

grepl("A", as.character(df$Category)) * 1
#> [1] 1 0 1 1 1

Если вы хотите, чтобы они все сразу, выполните:

sapply(c("A", "B", "C", "D"), function(x) grepl(x, as.character(df$Category)) * 1)
#>      A B C D
#> [1,] 1 1 1 0
#> [2,] 0 1 1 1
#> [3,] 1 0 1 0
#> [4,] 1 0 0 0
#> [5,] 1 0 1 1

Или, если вы хотите, чтобы они были столбцами в исходном фрейме данных, выполните: 1013 *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...