Я застрял на, казалось бы, простой задаче. Представьте себе следующее data.table:
dt1 <- data.table(ID = as.factor(c("202E", "202E", "202E")),
timestamp = as.POSIXct(c("2017-05-02 00:00:00",
"2017-05-02 00:15:00",
"2017-05-02 00:30:00")),
acceleration_raw = c("-0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.727 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.727 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.164 -0.703 0.656 0.141 -0.703 0.656 0.164 -0.703 0.656 0.141 -0.703 0.656 0.141 -0.703 0.656 0.141 -0.703 0.656 0.141",
"-0.703 0.680 0.117 -0.680 0.680 0.117 -0.680 0.680 0.117 -0.680 0.680 0.117 -0.680 0.680 0.117 -0.680 0.680 0.117 -0.680 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.680 0.680 0.117 -0.703 0.680 0.117 -0.680 0.680 0.117 -0.703 0.680 0.117 -0.680 0.680 0.117 -0.703 0.680 0.117 -0.680 0.680 0.117 -0.680 0.680 0.117 -0.680 0.680 0.117 -0.680 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.680 0.680 0.117 -0.680 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117 -0.703 0.680 0.117",
"-0.750 0.586 0.117 -0.773 0.586 0.117 -0.773 0.609 0.117 -0.773 0.586 0.117 -0.773 0.586 0.117 -0.773 0.586 0.117 -0.773 0.586 0.117 -0.773 0.586 0.117 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.750 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.141 -0.773 0.586 0.117 -0.773 0.586 0.141 -0.773 0.586 0.117 -0.773 0.586 0.117 -0.773 0.586 0.117 -0.773 0.586 0.117 -0.773 0.586 0.117 -0.773 0.586 0.117 -0.773 0.586 0.141 -0.773 0.586 0.117 -0.773 0.586 0.117 -0.773 0.586 0.117 -0.773 0.586 0.117 -0.773 0.586 0.117 -0.773 0.586 0.117"))
Created on 2022-11-17 with reprex v2.0.2
Идея состоит в том, что я хочу разделить столбец acceleration_raw на 3 разных: acc_x, acc_y и acc_z. Каждая строка acceleration_raw представляет собой строку символов, что в конечном итоге приводит к 120 числовым наблюдениям. Я хочу разделить acceleration_raw, а затем взять каждое значение из первой строки и далее с шагом 3 и поместить его в acc_x, каждое значение из второй строки и далее и поместить его в acc_y, и, наконец, каждое значение из третьей строки и далее и поставить на acc_z.
Сначала я попытался отделить acceleration_raw с separate_rows от dplyr:
library('tidyverse')
library('data.table')
dt1 <- dt1 %>%
separate_rows(acceleration_raw, sep = " ", convert = F)
Created on 2022-11-17 with reprex v2.0.2
И после этого:
library('tidyverse')
library('data.table')
dt1 <- dt1 %>%
separate_rows(acceleration_raw, sep = " ", convert = F) %>%
mutate(acc_x = seq(acceleration_raw, from = 1, to = length(dt1), by = 3),
acc_y = seq(acceleration_raw, from = 2, to = length(dt1), by = 3),
acc_z = seq(acceleration_raw, from = 3, to = length(dt1), by = 3))
#> Warning in seq.default(acceleration_raw, from = 1, to = length(dt1), by = 3):
#> first element used of 'length.out' argument
#> Error in `mutate()`:
#> ! Problem while computing `acc_x = seq(acceleration_raw, from = 1, to =
#> length(dt1), by = 3)`.
#> Caused by error in `ceiling()`:
#> ! non-numeric argument to mathematical function
Created on 2022-11-17 with reprex v2.0.2
Любые предложения о том, как действовать?
Вы можете использовать pivot_wider и unnest:
library(tidyverse)
dt1 %>%
separate_rows(acceleration_raw, sep = " ", convert = F) %>%
mutate(id = rep(c("acc_x", "acc_y", "acc_z"), times = nrow(.) / 3)) %>%
pivot_wider(names_from = id, values_from = acceleration_raw, values_fn = list) %>%
unnest(cols = c("acc_x", "acc_y", "acc_z"))
Это возвращает
# A tibble: 120 × 5
ID timestamp acc_x acc_y acc_z
<fct> <dttm> <chr> <chr> <chr>
1 202E 2017-05-02 00:00:00 -0.703 0.656 0.164
2 202E 2017-05-02 00:00:00 -0.703 0.656 0.164
3 202E 2017-05-02 00:00:00 -0.703 0.656 0.164
4 202E 2017-05-02 00:00:00 -0.703 0.656 0.164
5 202E 2017-05-02 00:00:00 -0.703 0.656 0.164
6 202E 2017-05-02 00:00:00 -0.703 0.656 0.164
7 202E 2017-05-02 00:00:00 -0.703 0.656 0.164
8 202E 2017-05-02 00:00:00 -0.703 0.656 0.164
9 202E 2017-05-02 00:00:00 -0.703 0.656 0.164
10 202E 2017-05-02 00:00:00 -0.703 0.656 0.164
# … with 110 more rows
Tbh: Это выглядит очень странно.
Этот выглядит очень хорошо. ` mutate(id = rep(c("acc_x", "acc_y", "acc_z"), times = nrow(.) / 3)) `
У меня не получилось pivot_wider без NA, поэтому решение не оптимальное:
library(tidyverse)
dt1 %>%
as_tibble() %>%
separate_rows(acceleration_raw, sep = " ") %>%
group_by(group = as.integer(gl(n(), n()/3, n()))) %>%
mutate(id = row_number()) %>%
mutate(group = case_when(group == 1 ~ "acc_x",
group == 2 ~ "acc_y",
group == 3 ~ "acc_z")) %>%
pivot_wider(names_from = group, values_from = acceleration_raw) %>%
mutate(acc_y = lead(acc_y,n()/3),
acc_z = lead(acc_z,n()/3*2)) %>%
na.omit()
# A tibble: 120 x 6
ID timestamp id acc_x acc_y acc_z
<fct> <dttm> <int> <chr> <chr> <chr>
1 202E 2017-05-02 00:00:00 1 -0.703 -0.703 -0.750
2 202E 2017-05-02 00:00:00 2 0.656 0.680 0.586
3 202E 2017-05-02 00:00:00 3 0.164 0.117 0.117
4 202E 2017-05-02 00:00:00 4 -0.703 -0.680 -0.773
5 202E 2017-05-02 00:00:00 5 0.656 0.680 0.586
6 202E 2017-05-02 00:00:00 6 0.164 0.117 0.117
7 202E 2017-05-02 00:00:00 7 -0.703 -0.680 -0.773
8 202E 2017-05-02 00:00:00 8 0.656 0.680 0.609
9 202E 2017-05-02 00:00:00 9 0.164 0.117 0.117
10 202E 2017-05-02 00:00:00 10 -0.703 -0.680 -0.773
# ... with 110 more rows
# i Use `print(n = ...)` to see more rows
Можете ли вы привести пример желаемого результата? сколько строк, по вашему мнению, должно иметь результирующий df?