Разверните фрейм данных и добавьте новую переменную - PullRequest
1 голос
/ 11 апреля 2020

У меня есть фрейм данных, структурированный так: +----------+------+--------+-------+ | Location | year | group1 | Value |<br> +----------+------+--------+-------+ | a | 2020 | 1 | x | | a | 2020 | 2 | y | | a | 2020 | 3 | z | | a | 2021 | 1 | x | | a | 2021 | 2 | y | | a | 2021 | 3 | z | | b | 2020 | 1 | x | | b | 2020 | 2 | y | | b | 2020 | 3 | z | +----------+------+--------+-------+ Я хотел бы расширить фрейм данных, включив в него 3 строки для каждой комбинации местоположения, года и группы1, и сгенерировать переменную group2, которая идентифицирует эти новые комбинации (1-3 ). В идеале фрейм данных должен выглядеть следующим образом: +----------+------+--------+-------+--------+ | Location | year | group1 | Value | group2 | +----------+------+--------+-------+--------+ | a | 2020 | 1 | x | 1 | | a | 2020 | 1 | x | 2 | | a | 2020 | 1 | x | 3 | | a | 2020 | 2 | y | 1 | | a | 2020 | 2 | y | 2 | | a | 2020 | 2 | y | 3 | | ... | ... |... |... |... | +----------+------+--------+-------+--------+

Мне удалось расширить фрейм данных до правильного количества строк, используя следующий код:

df[rep(seq_len(nrow(df)),3), 1:4]

Но не могу понять, как добавить переменную group2, показанную выше.

Ответы [ 3 ]

1 голос
/ 11 апреля 2020

С tidyr вы можете использовать expand - это расширит ваш фрейм данных до всех комбинаций значений с вашей последовательностью от 1 до 3:

library(tidyverse)

df %>%
  group_by(Location, year, group1, Value) %>%
  expand(group2 = 1:3)

Вывод

   Location  year group1 Value group2
   <fct>    <dbl>  <int> <fct>  <int>
 1 a         2020      1 x          1
 2 a         2020      1 x          2
 3 a         2020      1 x          3
 4 a         2020      2 y          1
 5 a         2020      2 y          2
 6 a         2020      2 y          3
 ...

Ваш подход выглядит близко, и я полагаю, вы могли бы просто добавить group2 следующим образом:

cbind(df[rep(seq_len(nrow(df)), each = 3), ], group2 = 1:3)
0 голосов
/ 11 апреля 2020

Мы можем использовать crossing из tidyr

library(tidyr)
library(dplyr)
crossing(df1, group2 = 1:3)
# A tibble: 27 x 5
#   Location  year group1 Value group2
#   <chr>    <int>  <int> <chr>  <int>
# 1 a         2020      1 x          1
# 2 a         2020      1 x          2
# 3 a         2020      1 x          3
# 4 a         2020      2 y          1
# 5 a         2020      2 y          2
# 6 a         2020      2 y          3
# 7 a         2020      3 z          1
# 8 a         2020      3 z          2
# 9 a         2020      3 z          3
#10 a         2021      1 x          1
# … with 17 more rows

Или создать столбец list, а затем unnest

df1  %>%
       mutate(group2 = list(1:3)) %>% 
       unnest(c(group2))

data

df1 <- structure(list(Location = c("a", "a", "a", "a", "a", "a", "b", 
"b", "b"), year = c(2020L, 2020L, 2020L, 2021L, 2021L, 2021L, 
2020L, 2020L, 2020L), group1 = c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 
2L, 3L), Value = c("x", "y", "z", "x", "y", "z", "x", "y", "z"
)), class = "data.frame", row.names = c(NA, -9L))
0 голосов
/ 11 апреля 2020

Вот решение, которое вы ищете

library(dplyr)

# 1. Data set
df <- data.table(
  location = c("a","a","a","a","a","a","b","b","b"),
  year = c(2020,2020,2020,2021,2021,2021,2020,2020,2020),
  group1 = c(1,2,3,1,2,3,1,2,3),
  value = c("x","y","z","x","y","z","x","y","z"),
  stringsAsFactors = FALSE)

# 2. Your code to expand data frame
df <- df[rep(seq_len(nrow(df)), 3), 1:4]

# 3. Arrange
df <- df %>% arrange(location, year, group1, value)

# 4. Add 'group2'
df <- df %>% 
  group_by(location, year, group1, value) %>% 
  mutate(group2 = cumsum(group1) / group1) %>% 
  arrange(location, year, group1, value, group2)

Надеюсь, что оно работает

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...