вернуть несколько (несколько столбцов в один столбец) - PullRequest
0 голосов
/ 21 марта 2019

У меня есть набор данных с ответами из опроса из 17 вопросов (10 вопросов по 5 или 7 вопросов по 7-балльной шкале), и теперь формат данных дает мне 5 или 7 столбцов для каждого ответа на вопрос (True или False), который похож на горячий стиль кодирования. И я хочу преобразовать эти столбцы обратно в 15 отдельных столбцов.

Если быть более точным, данные, которые у меня есть, выглядят следующим образом

        Q1.1  Q1.2  Q1.3 Q1.4 Q1.5 Q1.6 Q1.7 .... Q17.1 Q17.2 ... Q17.5 
row1     T     F      F    F    F    F    F         F     T          F
  ...               ...
row2000  F     T      F    F    F    F    F         T     F          F

желаемый формат -

        Q1  Q2 .... Q17
row1    1    4       2  # with number indicating the value that the column is True
           ....
row2000 2    3       1  #(e.g., if Q2.4 is T, then for Q2, it is 4).

Ответы [ 2 ]

2 голосов
/ 21 марта 2019

Подход Base R с использованием split.default и max.col.Используя split.default, мы можем разделить столбцы на основе шаблона в их имени, чтобы каждый вопрос был разделен на список.Предполагая, что у каждого вопроса будет только одно значение TRUE, мы можем использовать max.col, чтобы найти индекс TRUE.

sapply(split.default(df, sub("\\..*", "", names(df))), max.col)

#     Q1 Q2
#[1,]  1  2
#[2,]  6  5

data

df <-read.table(text = "Q1.1 Q1.2 Q1.3 Q1.4 Q1.5 Q1.6 Q1.7 Q2.1 Q2.2  Q2.3 Q2.4 Q2.5
T     F      F    F    F    F    F         F     T          F F F
F     F      F    F    F    T    F         F     F          F F T", header = T)

Предполагается, что класс ваших данных «логичен».Если «T» / «F» хранятся в символьном формате (как в ответе @Maurits), нам нужно сначала преобразовать их в логические.

Использование данных @Maurits Evers

df[] <- lapply(df, as.logical)
sapply(split.default(df, sub("\\..*", "", names(df))), max.col)

#     Q1 Q17
#[1,]  1   2
#[2,]  2   1
1 голос
/ 21 марта 2019

Вот вариант tidyverse:

library(tidyverse)
df %>%
    rownames_to_column("row") %>%
    gather(k, v, -row) %>%
    separate(k, c("question", "part"), sep = "\\.") %>%
    filter(v == "T") %>%
    group_by(row) %>%
    select(-v) %>%
    spread(question, part)
## A tibble: 2 x 3
## Groups:   row [2]
#  row     Q1    Q17
#  <chr>   <chr> <chr>
#1 row1    1     2
#2 row2000 2     1

Я предполагаю, что ваши исходные данные содержат "T" / "F" как character записей. Если они на самом деле TRUE / FALSE, вы должны изменить filter(v == "T") на filter(v == TRUE).


Пример данных

df <- read.table(text =
    "Q1.1  Q1.2  Q1.3 Q1.4 Q1.5 Q1.6 Q1.7  Q17.1 Q17.2  Q17.5
row1     T     F      F    F    F    F    F         F     T          F
row2000  F     T      F    F    F    F    F         T     F          F", colClasses = "character")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...