Как переупорядочить строки в алфавитном порядке по отдельным группам, несмотря на общие значения между группами? - PullRequest
1 голос
/ 02 августа 2020

У меня есть этот фрейм данных:

df
   speaker                                                             actionx phase
31    <NA>                                                      are only four=  <NA>
33   ID1-P                       ((m: r hand holds up three fingers ifo face))     B     # group 1
35   ID1-G                       ((m: r hand holds up three fingers ifo face))     A     # group 1
37   ID1-P                       ((m: r hand holds up three fingers ifo face))     D     # group 1
39    <NA>                                                             (0.215)  <NA>
41   ID2-A                                                               =mhm,  <NA>
43    <NA>                                                             (0.270)  <NA>
45   ID1-A So:: if you take a leave of absence we are going going to be three=  <NA>
47   ID1-P                       ((m: r hand holds up three fingers ifo face))     E     # group 1
49    <NA>                                                             (0.282)  <NA>
74   ID2-A                                                 <no: yeah: it 's:>=  <NA>
76   ID1-G                       ((m: r hand holds up three fingers ifo face))     A     # group 2
78   ID1-P                       ((m: r hand holds up three fingers ifo face))     B     # group 2
80   ID1-A                                                      =we are !four!  <NA>
82   ID1-P                       ((m: r hand holds up three fingers ifo face))     C     # group 2
84   ID1-P                       ((m: r hand holds up three fingers ifo face))     E     # group 2
86    <NA>                                                             (0.031)  <NA>

Я хочу переупорядочить строки таким образом, чтобы группы в столбце phase были упорядочены в алфавитном порядке и непосредственно рядом друг с другом. Группы идентифицируются с помощью (i) букв от A до E и (ii) того факта, что значения в столбце actionx одинаковы.

Благодаря совету членов SO, я знаю как изменить порядок строк, если все группы имеют разные actionx значения между ними, а именно:

df <- df[order(match(df$actionx, unique(df$actionx)), df$phase), ]
# or:
library(dplyr)
df <- df %>% arrange(match(actionx, unique(actionx)), phase)

Однако иногда группы имеют одинаковые actionx значений между ними; например, в df, group 1 и group 2 разделяют значение ((m: r hand holds up three fingers ifo face)) в столбце actionx.

Как я могу переупорядочить строки по группам в алфавитном порядке c несмотря на совпадение значений в actionx для достижения этого ожидаемого результата ? (Обратите внимание, что буквы от A до E не должны встречаться более одного раза в группе.)

df[c(1,3,2,4,9,5:8,10:13,15:16,14,17),]
   speaker                                                             actionx phase
31    <NA>                                                      are only four=  <NA>
35   ID1-G                       ((m: r hand holds up three fingers ifo face))     A
33   ID1-P                       ((m: r hand holds up three fingers ifo face))     B
37   ID1-P                       ((m: r hand holds up three fingers ifo face))     D
47   ID1-P                       ((m: r hand holds up three fingers ifo face))     E
39    <NA>                                                             (0.215)  <NA>
41   ID2-A                                                               =mhm,  <NA>
43    <NA>                                                             (0.270)  <NA>
45   ID1-A So:: if you take a leave of absence we are going going to be three=  <NA>
49    <NA>                                                             (0.282)  <NA>
74   ID2-A                                                 <no: yeah: it 's:>=  <NA>
76   ID1-G                       ((m: r hand holds up three fingers ifo face))     A
78   ID1-P                       ((m: r hand holds up three fingers ifo face))     B
82   ID1-P                       ((m: r hand holds up three fingers ifo face))     C
84   ID1-P                       ((m: r hand holds up three fingers ifo face))     E
80   ID1-A                                                      =we are !four!  <NA>
86    <NA>                                                             (0.031)  <NA>

Воспроизводимые данные :

df <- dput(t[c(17:26, 39:45), c(2,7,6)])
structure(list(speaker = c(NA, "ID1-P", "ID1-G", "ID1-P", NA, 
"ID2-A", NA, "ID1-A", "ID1-P", NA, "ID2-A", "ID1-G", "ID1-P", 
"ID1-A", "ID1-P", "ID1-P", NA), actionx = c("are only four=", 
"((m: r hand holds up three fingers ifo face))", "((m: r hand holds up three fingers ifo face))", 
"((m: r hand holds up three fingers ifo face))", "(0.215)", "=mhm,", 
"(0.270)", "So:: if you take a leave of absence we are going going to be three=", 
"((m: r hand holds up three fingers ifo face))", "(0.282)", "<no: yeah: it 's:>=", 
"((m: r hand holds up three fingers ifo face))", "((m: r hand holds up three fingers ifo face))", 
"=we are !four!", "((m: r hand holds up three fingers ifo face))", 
"((m: r hand holds up three fingers ifo face))", "(0.031)"), 
    phase = c(NA, "B", "A", "D", NA, NA, NA, NA, "E", NA, NA, 
    "A", "B", NA, "C", "E", NA)), row.names = c(31L, 33L, 35L, 
37L, 39L, 41L, 43L, 45L, 47L, 49L, 74L, 76L, 78L, 80L, 82L, 84L, 
86L), class = "data.frame")

1 Ответ

1 голос
/ 02 августа 2020

Вам понадобится двухступенчатый arrange():

library(dplyr)

df %>%
  arrange(data.table::rleid(!is.na(phase)),
          phase) %>%
  arrange(cumsum(coalesce(phase == "A", F)), ## if phase = "A", jump to the next group
          match(actionx, unique(actionx)))

#    speaker                                                             actionx phase
# 1     <NA>                                                      are only four=  <NA>
# 2    ID1-G                       ((m: r hand holds up three fingers ifo face))     A
# 3    ID1-P                       ((m: r hand holds up three fingers ifo face))     B
# 4    ID1-P                       ((m: r hand holds up three fingers ifo face))     D
# 5    ID1-P                       ((m: r hand holds up three fingers ifo face))     E
# 6     <NA>                                                             (0.215)  <NA>
# 7    ID2-A                                                               =mhm,  <NA>
# 8     <NA>                                                             (0.270)  <NA>
# 9    ID1-A So:: if you take a leave of absence we are going going to be three=  <NA>
# 10    <NA>                                                             (0.282)  <NA>
# 11   ID2-A                                                 <no: yeah: it 's:>=  <NA>
# 12   ID1-G                       ((m: r hand holds up three fingers ifo face))     A
# 13   ID1-P                       ((m: r hand holds up three fingers ifo face))     B
# 14   ID1-P                       ((m: r hand holds up three fingers ifo face))     C
# 15   ID1-P                       ((m: r hand holds up three fingers ifo face))     E
# 16   ID1-A                                                      =we are !four!  <NA>
# 17    <NA>                                                             (0.031)  <NA>

Примечание: Не объединяйте два arrange() вместе, потому что phase во втором arrange() в новом порядке.

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