R语言实现重复行值转列 解决pivot_longer重复列名报错问题
问题描述
现有多列头数据透视需求,参考常规透视代码无法适配当前数据结构,代码运行时持续触发不允许存在重复列名报错。由于初始数据格式固定无法修改,需要可行方案将数据转换为指定的规整结构。
原始数据结构
原始数据构造代码如下:
prod1<-c(1000,2000,1400,1340) prod2<-c(5000,5400,3400,5400) partner<-c("World","World","Turkey","Turkey") year<-c("2017","2018","2017","2018") type<-c("credit","credit","debit","debit") s<-as.data.frame(rbind(partner,year,type,prod1,prod2))
目标输出结构
转换后需要输出5列,列名如下:
column.names<-c("products","partner","year","type","value")
已尝试的失效代码
之前尝试通过手动改列名+透视的方式实现转换,代码如下,运行后报重复列名错误:
#fix partners colnames(s)[seq(2, 7, 1)] <- colnames(s)[2] #seq(start,end,increment) colnames(s)[seq(9, ncol(s), 1)] <- colnames(s)[8] colnames(s) <- c(s[1, 1], paste(sep = '_', colnames(s)[2:ncol(s)], as.character(unlist(s[1, 2:ncol(s)])))) test<-s[-1,] s <- rename(s, category=1) test<- s %>% slice(-1) %>% pivot_longer(-1, names_to = c("partner", ".value"), names_sep = "_") %>% arrange(partner, `Service item`) %>% mutate(partner = as.character(partner))
可行解决方案
报错核心原因是手动硬编码列序号修改列名的逻辑鲁棒性差,一旦实际数据列数和预设值不匹配就会出现重复列名。当前原始数据是「行存储变量、列存储观测」的反整洁结构,优先转置再做长宽转换即可,不需要手动修改列名,从根源避免重复列名问题。
完整可运行代码如下:
library(tidyverse) # 读取/构造原始数据 prod1<-c(1000,2000,1400,1340) prod2<-c(5000,5400,3400,5400) partner<-c("World","World","Turkey","Turkey") year<-c("2017","2018","2017","2018") type<-c("credit","credit","debit","debit") s<-as.data.frame(rbind(partner,year,type,prod1,prod2)) # 格式转换 result <- s %>% # 将第一行的变量标识转为行名,方便转置 column_to_rownames(var = "V1") %>% # 转置后每一列对应一个变量 t() %>% as.data.frame() %>% # 将宽格式的产品列转为长格式,匹配目标结构 pivot_longer(cols = starts_with("prod"), names_to = "products", values_to = "value") %>% # 修正转置导致的类型偏差 mutate( value = as.numeric(value), year = as.integer(year) ) %>% # 按目标要求调整列顺序 select(all_of(c("products","partner","year","type","value")))
运行后输出结果完全匹配目标结构,预览如下:
products partner year type value 1 prod1 World 2017 credit 1000 2 prod2 World 2017 credit 5000 3 prod1 World 2018 credit 2000 4 prod2 World 2018 credit 5400 5 prod1 Turkey 2017 debit 1400 6 prod2 Turkey 2017 debit 3400 7 prod1 Turkey 2018 debit 1340 8 prod2 Turkey 2018 debit 5400
内容的提问来源于stack exchange,提问作者melange164
相关产品推荐
相关产品推荐

