Изменение формы кадра данных путем перемещения части существующей строки в новую строку - PullRequest
0 голосов
/ 10 мая 2018

У меня есть данные в формате:

structure(list(choice = structure(c(1L, 1L, 2L, 1L), .Label = c("option1", 
"option2"), class = "factor"), option1var1 = structure(c(1L, 
1L, 1L, 1L), .Label = "A", class = "factor"), option1var2 = structure(c(1L, 
1L, 1L, 2L), .Label = c("B", "H"), class = "factor"), option2var1 = structure(c(1L, 
1L, 2L, 3L), .Label = c("C", "F", "I"), class = "factor"), option2var2 = structure(1:4, .Label = c("D", 
"E", "G", "K"), class = "factor")), .Names = c("choice", "option1var1", 
"option1var2", "option2var1", "option2var2"), class = "data.frame", row.names = c(NA, 
-4L))

Existing data

с шестью колоннами. Первый столбец содержит идентификатор респондента, второй столбец содержит данные о выборе, сделанном респондентом (либо option1 или option2), столбцы 3 и 4 содержат атрибуты, связанные с option1, а столбцы 4 и 5 содержат атрибуты, связанные с option2.

Я хочу преобразовать фрейм данных так, чтобы он выглядел следующим образом:

structure(list(respondent = c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L), 
    choice = c(1L, 0L, 1L, 0L, 0L, 1L, 1L, 0L), option = structure(c(1L, 
    2L, 1L, 2L, 1L, 2L, 1L, 2L), .Label = c("option1", "option2"
    ), class = "factor"), var1 = structure(c(1L, 2L, 1L, 2L, 
    1L, 3L, 1L, 4L), .Label = c("A", "C", "F", "I"), class = "factor"), 
    var2 = structure(c(1L, 2L, 1L, 3L, 1L, 4L, 5L, 6L), .Label = c("B", 
    "D", "E", "G", "H", "K"), class = "factor")), .Names = c("respondent", 
"choice", "option", "var1", "var2"), class = "data.frame", row.names = c(NA, 
-8L))

Desired result

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

Кажется, что нет никакой доступной информации об этом типе преобразования - ни здесь, ни в документации R, которую я нашел. Кто-нибудь знает, как это сделать?

1 Ответ

0 голосов
/ 10 мая 2018

Если исходный кадр данных равен df1, а окончательный результат равен df2.

library(tidyverse)

df2 <- df1 %>%
  mutate(respondent = 1:n()) %>%
  gather(Option, Value, starts_with("option")) %>%
  separate(Option, into = c("option", "Var"), sep = 7) %>%
  mutate(choice = ifelse(choice == option, 1L, 0L)) %>%
  spread(Var, Value) %>%
  select(respondent, choice, option, starts_with("var")) %>%
  arrange(respondent, option)
df2
#   respondent choice  option var1 var2
# 1          1      1 option1    A    B
# 2          1      0 option2    C    D
# 3          2      1 option1    A    B
# 4          2      0 option2    C    E
# 5          3      0 option1    A    B
# 6          3      1 option2    F    G
# 7          4      1 option1    A    H
# 8          4      0 option2    I    K
...