Использование pivot_longer и pivot_gather для очистки пустого заполненного фрейма данных - PullRequest
0 голосов
/ 27 февраля 2020

Друзья, привет! У меня есть данные около 2 миллионов сотрудников из одной отрасли и фирм, с которыми они работали с 2000-2019 гг. Это выглядит примерно так:

| ID |  FIRM | NAICS | Q1 | Q2 | Q3 | Q4 |
| A  |   001 |   100 |  1 |  1 |  1 |  1 |
| B  |   002 |   200 |  1 |  1 |  0 |  0 |
| B  |   003 |   100 |  0 |  0 |  1 |  1 |

... где NAICS - отраслевой код компании, в которой кто-то работал в данном квартале. Например, Человек A оставался в одной отрасли все четыре квартала; Персонал B перешел от Отрасль 200 к Отрасль 100 в Q3 за счет перемещения фирм.

Структура, которую я хотел бы закончить, выглядит следующим образом:

| ID |  Q1 |  Q2 |  Q3 |  Q4 |
| A  | 100 | 100 | 100 | 100 |
| B  | 200 | 200 | 100 | 100 |

... так, чтобы я мог отслеживать, из каких отраслей люди приходят, а затем строить что-то похожее на это анимированная диаграмма Санки .

Не могли бы вы помочь мне разобраться, как пройти от первого до второго? Я догадываюсь, что мне нужно использовать dplyr::pivot_longer() и dplyr::pivot_wider(), которые, как я понимаю, заменяют spread() и gather().

Ответы [ 2 ]

2 голосов
/ 27 февраля 2020

Здесь в основном три шага:

  • Увеличьте длину, чтобы каждый квартал был отдельной строкой
  • Удалите строки, в которых фирма была "неактивной" в этом квартале
  • Увеличьте ширину, разделив переменную "четверть" на столбцы
library(dplyr)
library(tidyr)

df %>%
  pivot_longer(
    cols = Q1:Q4,
    names_to = "quarter",
    values_to = "active"
  ) %>%
  filter(active == 1) %>%
  select(- FIRM, - active) %>%
  pivot_wider(
    names_from = quarter,
    values_from = NAICS
  )

Вывод:

# A tibble: 2 x 5
  ID       Q1    Q2    Q3    Q4
  <fct> <int> <int> <int> <int>
1 A       100   100   100   100
2 B       200   200   100   100
1 голос
/ 27 февраля 2020

Поскольку ваш фрейм данных содержит ID для 2 миллионов сотрудников, возможно, решение с функциями melt и dcast из пакета data.table будет для вас быстрее:

library(data.table)
setDT(dt)
Col <- paste("Q",1:4,sep = "")
dt.m <- melt(dt, measure = list(Col), variable.name = "quarter", value.name = "value")
dt.m <- dt.m[value == 1]
dt.m[,value:= NULL]
dt.m <- dcast(dt.m, ID~quarter, value.var = "NAICS")

   ID  Q1  Q2  Q3  Q4
1:  A 100 100 100 100
2:  B 200 200 100 100

Воспроизводимые данные

dt <- data.frame(ID = c("A","B","B"),
                 NAICS = c(100,200,100),
                 Q1 = c(1,1,0),
                 Q2 = c(1,1,0),
                 Q3 = c(1,0,1),
                 Q4 = c(1,0,1))
...