如何用tidyr::gather将列名及多行作为key整理数据?
解决方法
要实现你想要的效果,我们需要先把前两行的元数据(Gebiedsnummer和Postcode)转化为单独的列,再用tidyr::gather()把地点列聚合起来。以下是完整的可复现代码和步骤说明:
首先,先复现你的数据集:
library(tidyverse) df <- tibble( Aanduiding = c("Gebiedsnummer", "Postcode", "Leefbaar Rotterdam", "Partij van de Arbeid (P.v.d.A.)"), `Coolsingel 40 links` = c("1", "3011 AD", "124", "58"), `Goudseweg 15 links` = c("2", "3031 XH", "110", "65") )
接下来是处理步骤:
- 第一步:提取前两行的元数据,创建
Gebiedsnummer和Postcode的映射表,方便后续匹配 - 第二步:筛选出政党数据行,然后和元数据结合,再用
gather()转成长格式 - 第三步:整理列的顺序和类型(比如把票数转成数值型)
完整代码:
# 提取元数据:地点对应的Gebiedsnummer和Postcode metadata <- df %>% slice(1:2) %>% pivot_longer(cols = -Aanduiding, names_to = "Locatie", values_to = "Waarde") %>% pivot_wider(names_from = Aanduiding, values_from = Waarde) # 处理政党数据并和元数据合并 result <- df %>% slice(3:4) %>% gather(key = "Locatie", value = "Stemmen", -Aanduiding) %>% left_join(metadata, by = "Locatie") %>% # 调整列顺序,转成你要的5列 select(Partij = Aanduiding, Locatie, Gebiedsnummer, Postcode, Stemmen) %>% # 把Stemmen转成数值型(可选,根据需求) mutate(Stemmen = as.integer(Stemmen)) result
运行后得到的结果就是你想要的5列4行的数据框:
# A tibble: 4 × 5 Partij Locatie Gebiedsnummer Postcode Stemmen <chr> <chr> <chr> <chr> <int> 1 Leefbaar Rotterdam Coolsingel 40 links 1 3011 AD 124 2 Leefbaar Rotterdam Goudseweg 15 links 2 3031 XH 110 3 Partij van de Arbeid (P.v.d.A.) Coolsingel 40 links 1 3011 AD 58 4 Partij van de Arbeid (P.v.d.A.) Goudseweg 15 links 2 3031 XH 65
步骤解释
- 元数据处理:先把前两行转成宽格式,让每个地点对应自己的区域编号和邮编,这样后续合并的时候能准确匹配。
- 聚合地点列:用
gather()把两个地点列转成Locatie和Stemmen两列,保留政党名称。 - 合并与整理:通过
left_join把元数据和政党数据结合,最后调整列名和顺序,得到目标结构。
如果你更倾向于用tidyr的新函数pivot_longer()(现在官方更推荐这个替代gather()),可以把gather()那行换成:
pivot_longer(cols = -Aanduiding, names_to = "Locatie", values_to = "Stemmen")
效果是完全一致的。
内容的提问来源于stack exchange,提问作者Tdebeus
相关产品推荐
相关产品推荐

