使用 pivot_longer 和 pivot_gather 整理一个虚拟填充的数据框
Using pivot_longer and pivot_gather to tidy a dummy-filled dataframe
朋友们,您好!我有一个数据框,其中包含来自一个行业的大约 200 万名员工以及他们在 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 在 Q3 从 行业 200 移动到 行业 100 ] 靠搬家公司。
我希望得到的框架如下所示:
| ID | Q1 | Q2 | Q3 | Q4 |
| A | 100 | 100 | 100 | 100 |
| B | 200 | 200 | 100 | 100 |
... 这样我就可以跟踪人们来自哪些行业,然后构建类似于 this NYT animated sankey diagram 的东西。
你能帮我弄清楚如何从第一个到第二个吗?我的直觉是我需要使用 dplyr::pivot_longer()
和 dplyr::pivot_wider()
,我知道它们正在替换 spread()
和 gather()
。
这里基本上分为三个步骤:
- 让它变长,每个季度都有自己的行
- 删除公司在该季度"inactive"所在的行
- 扩大范围,将 "quarter" 变量扩展到列中
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
由于您的数据框包含 200 万员工的 ID,也许使用 data.table
包中的 melt
和 dcast
函数的解决方案对您来说会更快:
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))
朋友们,您好!我有一个数据框,其中包含来自一个行业的大约 200 万名员工以及他们在 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 在 Q3 从 行业 200 移动到 行业 100 ] 靠搬家公司。
我希望得到的框架如下所示:
| ID | Q1 | Q2 | Q3 | Q4 |
| A | 100 | 100 | 100 | 100 |
| B | 200 | 200 | 100 | 100 |
... 这样我就可以跟踪人们来自哪些行业,然后构建类似于 this NYT animated sankey diagram 的东西。
你能帮我弄清楚如何从第一个到第二个吗?我的直觉是我需要使用 dplyr::pivot_longer()
和 dplyr::pivot_wider()
,我知道它们正在替换 spread()
和 gather()
。
这里基本上分为三个步骤:
- 让它变长,每个季度都有自己的行
- 删除公司在该季度"inactive"所在的行
- 扩大范围,将 "quarter" 变量扩展到列中
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
由于您的数据框包含 200 万员工的 ID,也许使用 data.table
包中的 melt
和 dcast
函数的解决方案对您来说会更快:
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))