R - dplyr фрагмент карты для повторяющихся строк
У меня проблемы с совмещением slice
а также map
,
Мне интересно делать что-то похожее на это; который в моем случае преобразует компактный файл с периодом человека в длинный (последовательный) файл с периодом человека. Однако, поскольку мой файл слишком большой, мне нужно сначала разбить данные.
Мои данные выглядят так
group id var ep dur
1 A 1 a 1 20
2 A 1 b 2 10
3 A 1 a 3 5
4 A 2 b 1 5
5 A 2 b 2 10
6 A 2 b 3 15
7 B 1 a 1 20
8 B 1 a 2 10
9 B 1 a 3 10
10 B 2 c 1 20
11 B 2 c 2 5
12 B 2 c 3 10
Что мне нужно, это просто (ответ от этого)
library(dplyr)
dt %>% slice(rep(1:n(),.$dur))
Тем не менее, я заинтересован во введении split(.$group)
,
Как мне это сделать?
dt %>% split(.$group) %>% map_df(slice(rep(1:n(),.$dur)))
Не работает например.
Мой желаемый результат такой же, как dt %>% slice(rep(1:n(),.$dur))
который
group id var ep dur
1 A 1 a 1 20
2 A 1 a 1 20
3 A 1 a 1 20
4 A 1 a 1 20
5 A 1 a 1 20
6 A 1 a 1 20
7 A 1 a 1 20
8 A 1 a 1 20
9 A 1 a 1 20
10 A 1 a 1 20
.....
Но мне нужно split
эта операция, потому что файл слишком большой.
данные
dt = structure(list(group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 2L,
2L, 2L, 2L, 2L, 2L), .Label = c("A", "B"), class = "factor"),
id = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L,
2L, 2L), .Label = c("1", "2"), class = "factor"), var = structure(c(1L,
2L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 3L, 3L, 3L), .Label = c("a",
"b", "c"), class = "factor"), ep = structure(c(1L, 2L, 3L,
1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), .Label = c("1", "2",
"3"), class = "factor"), dur = c(20, 10, 5, 5, 10, 15, 20,
10, 10, 20, 5, 10)), .Names = c("group", "id", "var", "ep",
"dur"), row.names = c(NA, -12L), class = "data.frame")
2 ответа
map
принимает два аргумента: вектор / список в .x
и функция в .f
, Затем применяется .f
на всех элементах в .x
,
Функция, которую вы передаете map
неправильно отформатирован. Попробуй это:
f <- function(x) x %>% slice(rep(1:n(), .$dur))
dt %>%
split(.$group) %>%
map_df(f)
Вы также можете использовать это так:
dt %>%
split(.$group) %>%
map_df(slice, rep(1:n(), dur))
На этот раз вы проходите slice
функция к map
с дополнительными параметрами.
Я не совсем уверен, каков будет ваш конечный результат, но вы могли бы использовать tidyr
Вложить данные, которые вы хотите повторить, и простую функцию для расширения уровней ваших вложенных данных, очень похоже на ответ Тутучана.
expand_df <- function(df, repeats) {
df %>% slice(rep(1:n(), repeats))
}
dt %>%
tidyr::nest(var:ep) %>%
mutate(expanded = purrr::map2(data, dur, expand_df)) %>%
select(-data) %>%
tidyr::unnest()
Ответ Тутучана дает тот же результат, что и ваш оригинальный подход - это то, что вы искали? Я не знаю, будет ли это иметь какое-либо преимущество перед вашим оригинальным методом.