You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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)

代码说明

  1. 标记Value类型:用grepl匹配带逗号的数字格式,区分出数值型的Value元素。
  2. 反转数据分组:从后往前判断组边界,当遇到Value或连续两个非Value元素时,标记为新组的起始点,生成group_id。
  3. 恢复顺序并编号:将数据转回原顺序,重新对组ID进行连续编号。
  4. 组内位置标记:给每个组内的元素分配1/2/3的位置序号,对应Make/Model/Value。
  5. 宽表转换:用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 18:35:10