R: Используйте сбор и распространение для переноса набора данных временного ряда из широкого в длинный - PullRequest
1 голос
/ 22 октября 2019

Итак, у меня есть набор данных временного ряда, который имеет широкую форму и не идеален для анализа. То, что я намеревался сделать, было использовать сбор и распространение, чтобы транспонировать данные так долго, как я хочу.

Пример данных:

df <- data.frame(
  id = 1:3,
  "X1" = c(100,90,80),
  "X2" = c(100,90,80),
  "X3" = c(100,90,80),
  "X4" = c(100,90,80),
  "X5" = c(100,90,80)
)

> print(df)
  id  X1  X2  X3  X4  X5
1  1 100 100 100 100 100
2  2  90  90  90  90  90
3  3  80  80  80  80  80

Желаемый результат:

df2 <- data.frame(
  id = c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3),
  "month" = c(1,2,3,4,5,1,2,3,4,5,1,2,3,4,5),
  "balance" = c(100,100,100,100,100,90,90,90,90,90,80,80,80,80,80)
)
print(df2)
> print(df2)
   id month balance
1   1     1     100
2   1     2     100
3   1     3     100
4   1     4     100
5   1     5     100
6   2     1      90
7   2     2      90
8   2     3      90
9   2     4      90
10  2     5      90
11  3     1      80
12  3     2      80
13  3     3      80
14  3     4      80
15  3     5      80

Что я пробовал и что получил:

test_gather <-gather(df, "month", "value", X1:X5,na.rm = FALSE )
> print(test_gather)
   id month value
1   1    X1   100
2   2    X1    90
3   3    X1    80
4   1    X2   100
5   2    X2    90
6   3    X2    80
7   1    X3   100
8   2    X3    90
9   3    X3    80
10  1    X4   100
11  2    X4    90
12  3    X4    80
13  1    X5   100
14  2    X5    90
15  3    X5    80

Как показано выше, результат, который я получил, был просто неправильно отсортирован. Я хотел бы иметь возможность получить желаемый результат напрямую с помощью сбора / распространения без аранжировки в dplyr, если это возможно.

Ответы [ 2 ]

1 голос
/ 22 октября 2019

Для этого требуется arrange в столбце 'id' после gather и удаление префикса (при необходимости)

library(stringr)
library(dplyr)
library(tidyr)
df %>%
   gather(month, balance, -id) %>%
   arrange(id) %>%
   mutate(month = str_remove(month, "^X"))
#   id month balance
#1   1     1     100
#2   1     2     100
#3   1     3     100
#4   1     4     100
#5   1     5     100
#6   2     1      90
#7   2     2      90
#8   2     3      90
#9   2     4      90
#10  2     5      90
#11  3     1      80
#12  3     2      80
#13  3     3      80
#14  3     4      80
#15  3     5      80

С pivot_longer из tidyr_1.0.0, это не изменит порядок

df %>%
   pivot_longer(cols = -id, names_to = "month", values_to = "balance") %>%
   mutate(month = readr::parse_number(month))
# A tibble: 15 x 3
#      id month balance
#   <int> <dbl>   <dbl>
# 1     1     1     100
# 2     1     2     100
# 3     1     3     100
# 4     1     4     100
# 5     1     5     100
# 6     2     1      90
# 7     2     2      90
# 8     2     3      90
# 9     2     4      90
#10     2     5      90
#11     3     1      80
#12     3     2      80
#13     3     3      80
#14     3     4      80
#15     3     5      80
0 голосов
/ 22 октября 2019

Базовое решение:

# Reshape from wide to long: 

df2 <- 

  data.frame(

    reshape(

      df,

      direction = "long",

      varying = names(df)[names(df) != "id"],

      v.names = "value",

      idvar = "id",

      timevar = "month",

      times = names(df)[names(df) != "id"]

    ),

  row.names = NULL

)

# Order by id:

df2 <- df2[order(df2$id),]

# Keep only month numbers and coerce vector to numeric: 

df2$month <- as.numeric(gsub("^\\D+", "", df2$month))

Данные

df <- data.frame(

  id = 1:3,

  "X1" = c(100,90,80),

  "X2" = c(100,90,80),

  "X3" = c(100,90,80),

  "X4" = c(100,90,80),

  "X5" = c(100,90,80)
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...