Разверните data.frame / таблицу - PullRequest
2 голосов
/ 27 января 2020

Допустим, у меня есть data.frame / таблица, которую я хочу «развернуть», чтобы каждая строка преобразовывалась в последовательность повторяющихся строк (которую можно описать как группу), за исключением нового столбца, который будет иметь одинаковые значения во всех группах.

Итак, взяв следующий фрейм данных, мы хотим расширить его на столбец id, чтобы каждая строка теперь повторялась, но с новым столбцом q, который повторяется из 1-4 для каждой группы.

Способ, который я нашел, состоит в том, чтобы создать второй кадр данных на основе первого столбца id и с новыми значениями столбца, а затем соединить его с оригинал:

library(dplyr)

set.seed(42)

a <- data.frame(id = 1:5,
                value = runif(5))
a
#>   id     value
#> 1  1 0.9148060
#> 2  2 0.9370754
#> 3  3 0.2861395
#> 4  4 0.8304476
#> 5  5 0.6417455

b <- data.frame(id = rep(a$id, each = 4),
                q = 1:4)

left_join(a, b, by = "id")
#>    id     value q
#> 1   1 0.9148060 1
#> 2   1 0.9148060 2
#> 3   1 0.9148060 3
#> 4   1 0.9148060 4
#> 5   2 0.9370754 1
#> 6   2 0.9370754 2
#> 7   2 0.9370754 3
#> 8   2 0.9370754 4
#> 9   3 0.2861395 1
#> 10  3 0.2861395 2
#> 11  3 0.2861395 3
#> 12  3 0.2861395 4
#> 13  4 0.8304476 1
#> 14  4 0.8304476 2
#> 15  4 0.8304476 3
#> 16  4 0.8304476 4
#> 17  5 0.6417455 1
#> 18  5 0.6417455 2
#> 19  5 0.6417455 3
#> 20  5 0.6417455 4

Создано в 2020-01-27 пакетом Представить (v0.3.0)

Есть ли более прямой способ сделать это? В моем примере выше я использовал dplyr, но я могу так же легко принять синтаксис data.table, если это проще.

Ответы [ 3 ]

3 голосов
/ 27 января 2020

Это легко сделать с помощью функции crossing от tidyr :)

library(tidyverse)

a <- tibble(
  id = 1:5, value = runif(5)
)

crossing(a, q = 1:4)
#> # A tibble: 20 x 3
#>       id value     q
#>    <int> <dbl> <int>
#>  1     1 0.222     1
#>  2     1 0.222     2
#>  3     1 0.222     3
#>  4     1 0.222     4
#>  5     2 0.262     1
#>  6     2 0.262     2
#>  7     2 0.262     3
#>  8     2 0.262     4
#>  9     3 0.284     1
#> # … with 10 more rows

Создано в 2020-01-27 с помощью пакета Представить (v0.3.0 )

2 голосов
/ 27 января 2020

Если нам нужно rep лицензировать строки, это можно легко сделать с помощью uncount

library(dplyr)
library(tidyr)
library(data.table)
uncount(a, 4) %>% 
     mutate(q = rowid(id))

Или другой вариант - создать list столбец 'q' и затем unnest

a %>% 
   mutate(q = list(1:4)) %>%
   unnest(q)

Или в base R

transform(a[rep(seq_len(nrow(a)), 4), ], q = sequence(table(id)))

Или используя data.table

library(data.table)
setDT(a)[, .(q = 1:4),.(id, value)]

Или сначала реплицировать строки

setDT(a)[rep(seq_len(.N), .N)][, q := rep(1:4, length.out = .N)][]
1 голос
/ 28 января 2020

A data.table альтернатива:

setDT(a)
a[CJ(id = id, q = 1:4), on = .(id)]

База R:

expand_grid(a, q = 1:4)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...