Генерация серии столбцов, значения которых равны значениям столбца в другой строке - PullRequest
1 голос
/ 02 июля 2019

Допустим, у меня есть следующий набор данных:

data = read.table(text = "teamID quiz.1.answer quiz.1.solution quiz.2.answer quiz.2.solution
          1 2 2 4 4
          1 3 2 1 4", header = T)

> data
  teamID quiz.1.answer quiz.1.solution quiz.2.answer quiz.3.solution
1      1             2               2             4               4
2      1             3               2             1               4

Я хотел бы создать столбец для каждого человека в команде (лиц с одинаковым уникальным идентификатором команды), который соответствует значениям другого человекав их команде.Так, например:

data_final = read.table(text = "teamID quiz.1.answer quiz.1.solution quiz.2.answer quiz.2.solution partner_quiz.1.answer partner_quiz.1.solution partner_quiz.2.answer partner_quiz.2.solution
          1 2 2 4 4 3 2 1 4
          1 3 2 1 4 2 2 4 4", header = T)

При таком выводе:

> data_final
  teamID quiz.1.answer quiz.1.solution quiz.2.answer quiz.2.solution partner_quiz.1.answer partner_quiz.1.solution
1      1             2               2             4               4                     3                       2
2      1             3               2             1               4                     2                       2
  partner_quiz.2.answer partner_quiz.2.solution
1                     1                       4
2                     4                       4

Все соответствующие столбцы будут снабжены суффиксом «ответ» или «решение».Будет только две команды.

Я могу эмулировать это поведение с помощью следующего кода для каждой переменной.Однако в фактическом наборе данных у меня более 100 вопросов и решений для викторин, поэтому мне нужно найти способ сделать это для переменных, соответствующих конкретному запросу регулярного выражения.А именно, викторина [номер 1-100] .ответ или решение

data <- transform(data,partner_quiz.1.answer=ave(quiz.1.answer,teamID,FUN=rev))

Ответы [ 3 ]

4 голосов
/ 02 июля 2019

Если вы знаете, что в каждой группе только 2 человека, переключите строки, а затем перезапишите новый блок переменных:

nms <- names(data)[-1]
data <- data[order(data$teamID),]
data[paste0("partner_",nms)] <- data[seq_len(nrow(data)) + c(1,-1), nms]
data
#  teamID quiz.1.answer quiz.1.solution quiz.2.answer quiz.2.solution
#1      1             2               2             4               4
#2      1             3               2             1               4
#  partner_quiz.1.answer partner_quiz.1.solution partner_quiz.2.answer
#1                     3                       2                     1
#2                     2                       2                     4
#  partner_quiz.2.solution
#1                       4
#2                       4
4 голосов
/ 02 июля 2019

a data.table решение:

dt <- data.table(df)

newcols <- paste0("partner_", names(dt)[2:5])

dt[, c(newcols) := .SD[order(-.I)], by = teamID]

c(newcols) := присваивает столбцам, указанным в newcols. Он присваивает содержимое .SD, которое является подмножеством данных (следовательно, SD), которое в этом случае является данными, отфильтрованными для каждого teamID. [order(-.I)] меняет порядок подмножества (.I - это i-й элемент в teamID -группе), поэтому order(-.I) поставит ученика № 2 первым и № 1 следующим. Часть by говорит сама за себя.

Использованные данные:

df = read.table(text = "teamID quiz.1.answer quiz.1.solution quiz.2.answer quiz.2.solution
1 2 2 4 4
1 3 2 1 4", header = T)

Обратите внимание, что я избегал использования data, так как это имя функции в пакете utils.

2 голосов
/ 02 июля 2019

Используя dplyr, мы можем инвертировать номера строк по группам, переименовать столбцы и связать этот кадр данных с исходным.

library(dplyr)

bind_cols(data, data %>%
                 group_by(teamID) %>%
                 slice(n() : 1) %>%
                 ungroup() %>%
                 select(-teamID) %>%
                 rename_all(~paste0("partner_", .)))

#  teamID quiz.1.answer quiz.1.solution quiz.2.answer quiz.2.solution partner_quiz.1.answer
#1      1             2               2             4               4                     3
#2      1             3               2             1               4                     2

#  partner_quiz.1.solution partner_quiz.2.answer partner_quiz.2.solution
#1                       2                     1                       4
#2                       2                     4                       4

Если есть другие столбцы, и мы хотим выбрать только те, которыев конце "solution" или "answer" мы можем использовать matches в select

bind_cols(data, data %>%
     select(teamID, matches("answer$|solution$")) %>%
     group_by(teamID) %>%
     slice(n() : 1) %>%
     ungroup() %>%
     select(-teamID) %>%
    rename_all(~paste0("partner_", .)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...