R: Группировка по столбцам независимо от порядка, затем выполнение функции по третичному столбцу. - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть выходные данные от нескольких функций TSdist, чтобы проверить разницу между несколькими временными рядами. Результирующая матрица была преобразована в фрейм данных с использованием melt для преобразования в один фрейм данных Первый столбец представляет идентификатор строки в виде столбца, а второй - столбцы. Я пытаюсь вычислить среднее сходство за весь период.

Я пытаюсь сгруппировать по первым двум столбцам, выполняя операции над третьим. Вот пример фрейма данных.

df <- data.frame(A = factor(x = c("A", "B", "A", "A"), levels = c("A", "B")),
             B = factor(x = c("B", "A", "A", "A"), levels = c("A", "B")),
             C= c(2,3,6,5))

Я попытался использовать dplyr для группировки по первым двум столбцам. Однако местоположение столбца необходимо игнорировать при выполнении операции. Например, первая строка в вышеупомянутом фрейме данных должна быть сгруппирована со второй строкой, так как они оба являются A и B. С естественным образом сгруппированы строки 3 и 4, выполняя функцию для каждой группы с использованием третьего столбца, например. mean().

Спасибо

Ответы [ 2 ]

0 голосов
/ 27 апреля 2018

Вы могли бы сделать ... (та же идея, что и у gather подхода @ MelissaKey) ...

library(data.table)
setDT(df)

# add a grouping variable found by sorting and pasting the first two cols
df[, g := 
  vapply(transpose(.SD), function(x) paste(sort(x), collapse=" "), "", USE.NAMES = FALSE)
, .SDcols=1:2]

# aggregate the third column with it
df[, lapply(.SD, mean), by=g, .SDcols=3]

#      g   C
# 1: A B 2.5
# 2: A A 5.5

Вы можете передавать имена столбцов в .SDcols вместо позиций, и это, как правило, лучше. См. Первый FAQ в vignette("datatable-faq") для справки, если интересно.

0 голосов
/ 27 апреля 2018

Я могу придумать два способа приблизиться к этому, используя dplyr. Если количество уровней невелико, вы можете просто создать новую переменную взаимодействия и использовать fct_recode для исправления (например, от BA до AB).

Это решение выглядит так:

library(dplyr)
library(forcats)
df %>%
  mutate(
    AB = interaction(A, B, sep = ""),
    AB = fct_recode(AB, AB = "BA")
  ) 

Более надежное решение требует еще нескольких шагов, но должно работать независимо от количества уровней в вашем фактическом наборе данных:

library(tidyr)
df %>%
  mutate(id = 1:length(A)) %>%
  gather(group_id, group, A:B) %>%
  group_by(id) %>%
  summarize(
    AB = paste0(sort(group), collapse = ""),
    C = C[1]
  )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...