如何用tidyverse将含NA值的单列拆分为Make/Model/Value三列?
基于tidyverse的单列数据重排方案
原始数据
df <- tibble(value = c("Ford", "Focus", "2,300", "Chevy", "15", "Toyota", "245", "Honda", "Nissan"))
目标格式
Make Model Value Ford Focus 2,300 Chevy NA 15 Toyota NA 245 Honda NA NA Nissan NA NA
解决方案代码
library(tidyverse) # 构造原始数据 df <- tibble(value = c("Ford", "Focus", "2,300", "Chevy", "15", "Toyota", "245", "Honda", "Nissan")) result <- df %>% # 标记数值型的Value(匹配带逗号的数字格式) mutate(is_value = grepl("^\\d+,?\\d*$", value)) %>% # 反转数据,从后往前识别组边界 arrange(desc(row_number())) %>% # 生成组ID:遇到Value或连续非Value元素时开启新组 mutate(group_id = cumsum(ifelse(row_number() == 1, TRUE, is_value[row_number()-1] | (!is_value[row_number()] & !is_value[row_number()-1])))) %>% # 恢复原顺序并重新编号组ID arrange(desc(group_id)) %>% mutate(group_id = dense_rank(group_id)) %>% # 给组内元素分配位置序号(1=Make,2=Model,3=Value) group_by(group_id) %>% mutate(pos = row_number()) %>% ungroup() %>% # 转换为宽表并重命名列 pivot_wider(names_from = pos, values_from = value, names_transform = function(x) case_when(x==1 ~ "Make", x==2 ~ "Model", x==3 ~ "Value")) %>% # 填充缺失值为NA,整理列顺序 select(Make, Model, Value) %>% replace_na(list(Model = NA_character_, Value = NA_character_)) # 输出结果 print(result, n=Inf)
代码说明
- 标记Value类型:用
grepl匹配带逗号的数字格式,区分出数值型的Value元素。 - 反转数据分组:从后往前判断组边界,当遇到Value或连续两个非Value元素时,标记为新组的起始点,生成
group_id。 - 恢复顺序并编号:将数据转回原顺序,重新对组ID进行连续编号。
- 组内位置标记:给每个组内的元素分配1/2/3的位置序号,对应Make/Model/Value。
- 宽表转换:用
pivot_wider将长表转成宽表,重命名列后填充缺失值为NA,得到目标格式。
输出结果
# A tibble: 5 × 3 Make Model Value <chr> <chr> <chr> 1 Ford Focus 2,300 2 Chevy NA 15 3 Toyota NA 245 4 Honda NA NA 5 Nissan NA NA
内容的提问来源于stack exchange,提问作者matt_lnrd
相关产品推荐
相关产品推荐

