Как отсортировать несколько столбцов в группах на основе строкового вектора в группе в R? - PullRequest
0 голосов
/ 09 марта 2019

Я работаю с данными о выборах, где на каждых выборах кандидаты перечислены в соответствии со случайно сгенерированным алфавитом; Я пытаюсь воссоздать порядок кандидатов. Таким образом, для выборов 1 алфавит может быть «B, C, A», и, таким образом, кандидаты на этих выборах будут появляться в следующем порядке: «Брайант, Карлсон, Андерсон»; кандидаты на выборах 2, где алфавит «C, A, B», будут перечислены как «Чавес, Армстронг, Браун»; и так далее.

Мой план состоял в том, чтобы разбить имена на столбцы с отдельными буквами, а затем отсортировать столбцы, используя алфавит для этих выборов. Вот минимальный df:

set.seed(124)

a2000 <- sample(letters[1:9], r = F)
a2001 <- sample(letters[1:9], r = F)
a2002 <- sample(letters[1:9], r = F)


d <- data.frame(
  electionid = rep(1:3, each = 3),
  year = rep(2000:2002, each = 3),
  last1 = sample(letters[1:9], r = T),
  last2 = sample(letters[1:9], r = T),
  alph = I(list(a2000,a2000,a2000,a2001,a2001,a2001,a2002,a2002,a2002)))

last_cols <- c("last1", "last2") # in real dataset, many more columns here

newd <- d %>% 
  group_by(electionid) %>% # order columns within election, not within dataframe
  arrange_at(last_cols, funs(factor(., levels = alph[[1]]))) %>% # set new alphabet for each variable
  mutate(race_order = seq(n())) %>% # create ordering variable
  arrange(electionid) # rearrange for easy checking

Ключевая проблема заключается в том, что каждый алфавит встречается синонимично с electionid, поэтому попытка разложить каждый столбец (last1 и last2) только с помощью переменной alph возвращает ошибку оценки (например, factor level [2] is duplicated. ). Когда я использую такие параметры, как alph[[1]] (в примере), unique(alph), first(alph), coalesce(alph) и т. Д., Я избавляюсь от ошибки, но кажется, что либо используется первый алфавит, который встречается в наборе данных (a2000), или вообще не сортировать.

Что я получу с кодом выше (используя dput):

structure(list(electionid = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 
3L), year = c(2000L, 2000L, 2000L, 2001L, 2001L, 2001L, 2002L, 
2002L, 2002L), last1 = structure(c(1L, 1L, 4L, 3L, 2L, 6L, 3L, 
5L, 5L), .Label = c("a", "d", "f", "g", "h", "i"), class = "factor"), 
    last2 = structure(c(1L, 6L, 6L, 5L, 2L, 4L, 3L, 3L, 4L), .Label = c("c", 
    "d", "e", "g", "h", "i"), class = "factor"), alph = structure(list(
        c("b", "e", "g", "d", "c", "f", "h", "a", "i"), c("b", 
        "e", "g", "d", "c", "f", "h", "a", "i"), c("b", "e", 
        "g", "d", "c", "f", "h", "a", "i"), c("a", "h", "g", 
        "d", "b", "e", "f", "i", "c"), c("a", "h", "g", "d", 
        "b", "e", "f", "i", "c"), c("a", "h", "g", "d", "b", 
        "e", "f", "i", "c"), c("a", "g", "h", "e", "d", "b", 
        "f", "i", "c"), c("a", "g", "h", "e", "d", "b", "f", 
        "i", "c"), c("a", "g", "h", "e", "d", "b", "f", "i", 
        "c")), class = "AsIs"), race_order = c(1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L)), class = c("grouped_df", "tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -9L), vars = "electionid", indices = list(
    0:2, 3:5, 6:8), drop = TRUE, group_sizes = c(3L, 3L, 3L), biggest_group_size = 3L, labels = structure(list(
    electionid = 1:3), class = "data.frame", row.names = c(NA, 
-3L), vars = "electionid", indices = list(0:2, 3:5, 6:8), drop = TRUE, group_sizes = c(3L, 3L, 3L), biggest_group_size = 3L))

Который печатается как:

# A tibble: 9 x 6
# Groups:   electionid [3]
  electionid  year last1 last2 alph      race_order
       <int> <int> <fct> <fct> <I(list)>      <int>
1          1  2000 c     b     <chr [9]>          1 # This is with alphabet a2000
2          1  2000 h     i     <chr [9]>          2 # This is with alphabet a2000
3          1  2000 d     b     <chr [9]>          3 # This is with alphabet a2000
4          2  2001 h     c     <chr [9]>          1 # This is with alphabet a2001
5          2  2001 c     b     <chr [9]>          2 # This is with alphabet a2001
6          2  2001 d     h     <chr [9]>          3 # This is with alphabet a2001
7          3  2002 h     g     <chr [9]>          1 # This is with alphabet a2002
8          3  2002 a     c     <chr [9]>          2 # This is with alphabet a2002
9          3  2002 i     d     <chr [9]>          3 # This is with alphabet a2002

Что бы я хотел получить:

# A tibble: 9 x 6
# Groups:   electionid [3]
  electionid  year last1 last2 alph      race_order
       <int> <int> <fct> <fct> <I(list)>      <int>
1          1  2000 d     b     <chr [9]>          1 # Previously ranked 3
2          1  2000 h     i     <chr [9]>          2
3          1  2000 c     b     <chr [9]>          3 # Previously ranked 1
4          2  2001 c     b     <chr [9]>          1 # Previously ranked 2
5          2  2001 h     c     <chr [9]>          2 # Previously ranked 1
6          2  2001 d     h     <chr [9]>          3
7          3  2002 h     g     <chr [9]>          1 
8          3  2002 a     c     <chr [9]>          2
9          3  2002 i     d     <chr [9]>          3

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

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