R длинный к широкому с парой столбцов - PullRequest
3 голосов
/ 08 января 2020

Я пытаюсь преобразовать набор данных из длинного в широкий формат.

Мои входные данные ниже:

df <- data.frame(year = c(2011:2013),
             T1 = c("a", "b", "c"),
             T2 = c("b", "c", "d"),
             V1 = rep(1, 3),
             V2 = rep(2, 3))

, где желаемый результат равен

df2 <- data.frame(year = c(2011:2013),
              a = c(1, 0, 0),
              b = c(2, 1, 0),
              c = c(0, 2, 1),
              d = c(0, 0, 2))

Я думаю, что делает это более сложным (по крайней мере для меня), это Тот факт, что столбцы T1 и V1 являются "парами", и то же самое верно для T2 и V2. Попытка собрать столбцы T1 и T2, затем распространить (или dcast) это, но, похоже, не работает.

Вот то, что я пробовал.

require(data.table)
dt <- setDT(df)
tmp <- melt(dt, measure.vars = c("T1", "T2"))
dcast(tmp, year ~ value, value.var = c("V1", "V2"))

Когда я делаю это в виде дкаста, V1_a и V2_a принимают значения 1 и 2 соответственно, не позволяя мне сохранить структуру "пары".

Любая помощь будет принята с благодарностью! Спасибо!

Ответы [ 2 ]

3 голосов
/ 08 января 2020

Здесь мы можем использовать measure с patterns в синтаксисе data.table

library(data.table)
dcast(melt(setDT(df), measure = patterns("^T", "^V")), 
      year ~ value1, value.var = 'value2', fill = 0)
#   year a b c d
#1: 2011 1 2 0 0
#2: 2012 0 1 2 0
#3: 2013 0 0 1 2
2 голосов
/ 08 января 2020

Сначала вы можете использовать pivot_longer, чтобы получить данные в длинном формате с парами T и V отдельно, а затем использовать pivot_wider, чтобы переместить их обратно в широкоформатный формат.

library(dplyr)
library(tidyr)

df %>%
  pivot_longer(cols = -year, names_to = c(".value", "cols"), 
               names_pattern = "([A-Z])(\\d)") %>%
  select(-cols) %>%
  pivot_wider(names_from = T, values_from = V, values_fill = list(V = 0))

# A tibble: 3 x 5
#   year     a     b     c     d
#  <int> <dbl> <dbl> <dbl> <dbl>
#1  2011     1     2     0     0
#2  2012     0     1     2     0
#3  2013     0     0     1     2
...