Агрегировать и сворачивать вектор на основе при сохранении порядка - PullRequest
1 голос
/ 30 января 2020

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

+------+-----+----------+
| from | to  | priority |
+------+-----+----------+
|    1 |   8 |        1 |
|    2 |   6 |        1 |
|    3 |   4 |        1 |
|    4 |   5 |        3 |
|    5 |   6 |        4 |
|    6 |   2 |        5 |
|    7 |   8 |        2 |
|    4 |   3 |        5 |
|    2 |   1 |        1 |
|    6 |   6 |        4 |
|    1 |   7 |        5 |
|    8 |   4 |        6 |
|    9 |   5 |        3 |
+------+-----+----------+

Моя цель - сгруппировать столбец "to" на основе столбца from, но таким образом, чтобы, если переменная уже присутствовала в одном из столбцы, я не хотел бы принимать их во внимание в дальнейшем Кроме того, общий приоритет будет суммой всех приоритетов группы

Таким образом, результирующий кадр данных будет выглядеть так:

+------+------+----------------+
| from |  to  | Total Priority |
+------+------+----------------+
|    1 | 8, 7 |              6 |
|    2 |    6 |              1 |
|    3 |    4 |              1 |
|    9 |    5 |              3 |
+------+------+----------------+

Кроме того, я хотел бы сохранить тот же порядок, что и в исходной таблице, при группировке

Мне удалось свернуть столбец from с помощью пакета "splitstackshape", как указано в

library(splitstackshape)
cSplit(df, 'to', sep = ','
+        , direction = 'long')[, .(to = toString(unique(to)))
+                              , by = from]

Это вводит повторяющиеся значения. Мне было интересно, есть ли способ получить желаемый результат, используя любые другие пакеты

Ответы [ 2 ]

1 голос
/ 30 января 2020

Используя DF, воспроизводимый в конце заметки, сортируйте по from, давая DF2, а затем перебирайте все строки, удаляя все строки с дубликатом. Нам нужно все oop здесь, так как каждое удаление зависит от предыдущих. Наконец, суммируйте результат.

library(dplyr)

DF2 <- arrange(DF, from)

i <- 1
while(i <= nrow(DF2)) {
  ix <- seq_len(i-1)
  dup <- with(DF2, (to[i] %in% c(to[ix], from[ix])) | (from[i] %in% to[ix]))
  if (dup) DF2 <- DF2[-i, ] else i <- i + 1
}

DF2 %>%
  group_by(from) %>%
  summarize(to = toString(to), priority = sum(priority)) %>%
  ungroup

, давая:

# A tibble: 4 x 3
   from to    priority
  <int> <chr>    <int>
1     1 8, 7         6
2     2 6            1
3     3 4            1
4     9 5            3

Примечание

Lines <- "from | to  | priority
   1 |   8 |        1
   2 |   6 |        1
   3 |   4 |        1
   4 |   5 |        3
   5 |   6 |        4
   6 |   2 |        5
   7 |   8 |        2
   4 |   3 |        5
   2 |   1 |        1
   6 |   6 |        4
   1 |   7 |        5
   8 |   4 |        6
   9 |   5 |        3"
DF <- read.table(text = Lines, header = TRUE, sep = "|", strip.white = TRUE)
1 голос
/ 30 января 2020

Непонятно, как именно вы пытаетесь создать группы, но это, по крайней мере, приведет вас к правильному шагу:

library(tidyverse)

df <- tribble(~from, ~to, ~priority,
              1,8,1,
              2,6,1,
              3,4,1,
              4,5,3,
              5,6,4,
              6,2,5,
              7,8,2,
              4,3,5,
              2,1,1,
              6,6,4,
              1,7,5,
              8,4,6,
              9,5,3)

df %>%
  group_by(from) %>%
  summarise(to = toString(to),
            `Total Priority` = sum(priority, na.rm=T))

Ваш результат будет:

# A tibble: 9 x 3
   from to    `Total Priority`
  <dbl> <chr>            <dbl>
1     1 8, 7                 6
2     2 6, 1                 2
3     3 4                    1
4     4 5, 3                 8
5     5 6                    4
6     6 2, 6                 9
7     7 8                    2
8     8 4                    6
9     9 5                    3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...