#r #date
#r #Дата
Вопрос:
У меня есть список, в котором каждый элемент представляет собой фрейм данных, который помечает даты в продолжительности поездки для каждого человека.
group.l <- list(
data.frame(DATE = seq.Date(as.Date("2017-01-01"),
as.Date("2017-12-31"),
"days")) %>%
mutate(PERSON1_TRIP1 = ifelse(DATE %in% seq.Date(as.Date("2017-01-05"),
as.Date("2017-03-04"),
"days"), 1, 0)),
data.frame(DATE = seq.Date(as.Date("2017-01-01"),
as.Date("2017-12-31"),
"days")) %>%
mutate(PERSON1_TRIP2 = ifelse(DATE %in% seq.Date(as.Date("2017-04-15"),
as.Date("2017-06-04"),
"days"), 1, 0)),
data.frame(DATE = seq.Date(as.Date("2017-01-01"),
as.Date("2017-12-31"),
"days")) %>%
mutate(PERSON2_TRIP1 = ifelse(DATE %in% seq.Date(as.Date("2017-01-01"),
as.Date("2017-01-05"),
"days"), 1, 0)),
data.frame(DATE = seq.Date(as.Date("2017-01-01"),
as.Date("2017-12-31"),
"days")) %>%
mutate(PERSON2_TRIP2 = ifelse(DATE %in% seq.Date(as.Date("2017-11-15"),
as.Date("2017-12-04"),
"days"), 1, 0))
)
Пример 3-го элемента списка выглядит следующим образом
Я хотел бы иметь фрейм данных, в котором есть один столбец для Person, один столбец для номера поездки, а остальные столбцы будут представлять собой каждую дату, которая будет принимать 1, если поездка человека i x пришлась на дату этого столбца.
может быть, комбинация транспонирования с str_split будет работать? транспонирование превратило бы столбец даты в новые отдельные столбцы даты, а str_split разделил бы исходное имя столбца PERSON_TRIP на два отдельных столбца.
Мой реальный набор данных охватывает период с 2004 по 2019 год с тысячами комбинаций PERSON_TRIP, поэтому мне понадобится наиболее эффективный код для экономии вычислительного времени.
Ответ №1:
Используйте stringr::str_split_fixed()
:
data <-
map_dfr(
group.l,
function(df) {
df <- df %>%
mutate(
person_trip = names(df)[2]
)
df <-
bind_cols(
df %>% select(-person_trip) %>% setNames(c("date", "value")),
as.data.frame(stringr::str_split_fixed(df$person_trip, "_", 2)) %>%
setNames(c("person", "trip"))
)
}
) %>%
tidyr::pivot_wider(names_from = date, values_from = value) # this will give you what you want although I don't think spread the date value is a good idea
> data
# A tibble: 4 x 367
person trip `2017-01-01` `2017-01-02` `2017-01-03` `2017-01-04` `2017-01-05` `2017-01-06` `2017-01-07` `2017-01-08` `2017-01-09` `2017-01-10`
<chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 PERSO… TRIP1 0 0 0 0 1 1 1 1 1 1
2 PERSO… TRIP2 0 0 0 0 0 0 0 0 0 0
3 PERSO… TRIP1 1 1 1 1 1 0 0 0 0 0
4 PERSO… TRIP2 0 0 0 0 0 0 0 0 0 0
# … with 355 more variables: `2017-01-11` <dbl>, `2017-01-12` <dbl>, `2017-01-13` <dbl>, `2017-01-14` <dbl>, `2017-01-15` <dbl>,
# `2017-01-16` <dbl>, `2017-01-17` <dbl>, `2017-01-18` <dbl>, `2017-01-19` <dbl>, `2017-01-20` <dbl>, `2017-01-21` <dbl>, `2017-01-22` <dbl>,
# `2017-01-23` <dbl>, `2017-01-24` <dbl>, `2017-01-25` <dbl>, `2017-01-26` <dbl>, `2017-01-27` <dbl>, `2017-01-28` <dbl>, `2017-01-29` <dbl>,
# `2017-01-30` <dbl>, `2017-01-31` <dbl>, `2017-02-01` <dbl>, `2017-02-02` <dbl>, `2017-02-03` <dbl>, `2017-02-04` <dbl>, `2017-02-05` <dbl>,
# `2017-02-06` <dbl>, `2017-02-07` <dbl>, `2017-02-08` <dbl>, `2017-02-09` <dbl>, `2017-02-10` <dbl>, `2017-02-11` <dbl>, `2017-02-12` <dbl>,
# `2017-02-13` <dbl>, `2017-02-14` <dbl>, `2017-02-15` <dbl>, `2017-02-16` <dbl>, `2017-02-17` <dbl>, `2017-02-18` <dbl>, `2017-02-19` <dbl>,
# `2017-02-20` <dbl>, `2017-02-21` <dbl>, `2017-02-22` <dbl>, `2017-02-23` <dbl>, `2017-02-24` <dbl>, `2017-02-25` <dbl>, `2017-02-26` <dbl>,
# `2017-02-27` <dbl>, `2017-02-28` <dbl>, `2017-03-01` <dbl>, `2017-03-02` <dbl>, `2017-03-03` <dbl>, `2017-03-04` <dbl>, `2017-03-05` <dbl>,
# `2017-03-06` <dbl>, `2017-03-07` <dbl>, `2017-03-08` <dbl>, `2017-03-09` <dbl>, `2017-03-10` <dbl>, `2017-03-11` <dbl>, `2017-03-12` <dbl>,
# `2017-03-13` <dbl>, `2017-03-14` <dbl>, `2017-03-15` <dbl>, `2017-03-16` <dbl>, `2017-03-17` <dbl>, `2017-03-18` <dbl>, `2017-03-19` <dbl>,
# `2017-03-20` <dbl>, `2017-03-21` <dbl>, `2017-03-22` <dbl>, `2017-03-23` <dbl>, `2017-03-24` <dbl>, `2017-03-25` <dbl>, `2017-03-26` <dbl>,
# `2017-03-27` <dbl>, `2017-03-28` <dbl>, `2017-03-29` <dbl>, `2017-03-30` <dbl>, `2017-03-31` <dbl>, `2017-04-01` <dbl>, `2017-04-02` <dbl>,
# `2017-04-03` <dbl>, `2017-04-04` <dbl>, `2017-04-05` <dbl>, `2017-04-06` <dbl>, `2017-04-07` <dbl>, `2017-04-08` <dbl>, `2017-04-09` <dbl>,
# `2017-04-10` <dbl>, `2017-04-11` <dbl>, `2017-04-12` <dbl>, `2017-04-13` <dbl>, `2017-04-14` <dbl>, `2017-04-15` <dbl>, `2017-04-16` <dbl>,
# `2017-04-17` <dbl>, `2017-04-18` <dbl>, `2017-04-19` <dbl>, `2017-04-20` <dbl>, …
Ответ №2:
Мы можем связать list
элементы с bind_rows
помощью, использовать pivot_longer
для преобразования данных в «длинный» формат, separate
столбец «имя» в разделителе _
и изменить его обратно в «широкий» формат с помощью pivot_wider
library(dplyr)
library(tidyr)
library(data.table)
bind_rows(group.l) %>%
pivot_longer(cols = -DATE, values_drop_na = TRUE) %>%
separate(name, into = c("PERSON", "TRIP")) %>%
mutate(rn = rowid(PERSON, TRIP, DATE)) %>%
pivot_wider(names_from = DATE, values_from = value, values_fill = 0)
-вывод
# A tibble: 4 x 368
PERSON TRIP rn `2017-01-01` `2017-01-02` `2017-01-03` `2017-01-04` `2017-01-05` `2017-01-06` `2017-01-07` `2017-01-08` `2017-01-09`
<chr> <chr> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 PERSO… TRIP1 1 0 0 0 0 1 1 1 1 1
2 PERSO… TRIP2 1 0 0 0 0 0 0 0 0 0
3 PERSO… TRIP1 1 1 1 1 1 1 0 0 0 0
4 PERSO… TRIP2 1 0 0 0 0 0 0 0 0 0
# … with 356 more variables: `2017-01-10` <dbl>, `2017-01-11` <dbl>, `2017-01-12` <dbl>, `2017-01-13` <dbl>, `2017-01-14` <dbl>,
# `2017-01-15` <dbl>, `2017-01-16` <dbl>, `2017-01-17` <dbl>, `2017-01-18` <dbl>, `2017-01-19` <dbl>, `2017-01-20` <dbl>, `2017-01-21` <dbl>,
# `2017-01-22` <dbl>, `2017-01-23` <dbl>, `2017-01-24` <dbl>, `2017-01-25` <dbl>, `2017-01-26` <dbl>, `2017-01-27` <dbl>, `2017-01-28` <dbl>,
# `2017-01-29` <dbl>, `2017-01-30` <dbl>, `2017-01-31` <dbl>, `2017-02-01` <dbl>, `2017-02-02` <dbl>, `2017-02-03` <dbl>, `2017-02-04` <dbl>,
# `2017-02-05` <dbl>, `2017-02-06` <dbl>, `2017-02-07` <dbl>, `2017-02-08` <dbl>, `2017-02-09` <dbl>, `2017-02-10` <dbl>, `2017-02-11` <dbl>,
# `2017-02-12` <dbl>, `2017-02-13` <dbl>, `2017-02-14` <dbl>, `2017-02-15` <dbl>, `2017-02-16` <dbl>, `2017-02-17` <dbl>, `2017-02-18` <dbl>,
# `2017-02-19` <dbl>, `2017-02-20` <dbl>, `2017-02-21` <dbl>, `2017-02-22` <dbl>, `2017-02-23` <dbl>, `2017-02-24` <dbl>, `2017-02-25` <dbl>,
# `2017-02-26` <dbl>, `2017-02-27` <dbl>, `2017-02-28` <dbl>, `2017-03-01` <dbl>, `2017-03-02` <dbl>, `2017-03-03` <dbl>, `2017-03-04` <dbl>,
# `2017-03-05` <dbl>, `2017-03-06` <dbl>, `2017-03-07` <dbl>, `2017-03-08` <dbl>, `2017-03-09` <dbl>, `2017-03-10` <dbl>, `2017-03-11` <dbl>,
# `2017-03-12` <dbl>, `2017-03-13` <dbl>, `2017-03-14` <dbl>, `2017-03-15` <dbl>, `2017-03-16` <dbl>, `2017-03-17` <dbl>, `2017-03-18` <dbl>,
# `2017-03-19` <dbl>, `2017-03-20` <dbl>, `2017-03-21` <dbl>, `2017-03-22` <dbl>, `2017-03-23` <dbl>, `2017-03-24` <dbl>, `2017-03-25` <dbl>,
# `2017-03-26` <dbl>, `2017-03-27` <dbl>, `2017-03-28` <dbl>, `2017-03-29` <dbl>, `2017-03-30` <dbl>, `2017-03-31` <dbl>, `2017-04-01` <dbl>,
# `2017-04-02` <dbl>, `2017-04-03` <dbl>, `2017-04-04` <dbl>, `2017-04-05` <dbl>, `2017-04-06` <dbl>, `2017-04-07` <dbl>, `2017-04-08` <dbl>,
# `2017-04-09` <dbl>, `2017-04-10` <dbl>, `2017-04-11` <dbl>, `2017-04-12` <dbl>, `2017-04-13` <dbl>, `2017-04-14` <dbl>, `2017-04-15` <dbl>,
# `2017-04-16` <dbl>, `2017-04-17` <dbl>, `2017-04-18` <dbl>, `2017-04-19` <dbl>, …
>