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

R语言实现数据左移:将NA值移至右侧并归类项目

解决方法

方法一:使用dplyr + tidyr(推荐,代码可读性高)

先加载所需工具包,通过长格式转宽格式的思路实现非NA值左移:

library(dplyr)
library(tidyr)

# 原始数据
df <- structure(list(INVOICE_ID = 7367109:7367117, 
                     Edible = c("Edible", NA, NA, NA, NA, NA, NA, NA, "Edible"), 
                     Vape = c("Vape", NA, NA, NA, NA, NA, NA, NA, NA), 
                     Flower = c(NA, "Flower", "Flower", "Flower", "Flower", "Flower", "Flower", "Flower", "Flower"), 
                     Concentrate = c(NA, NA, NA, "Concentrate", NA, NA, NA, NA, NA)), 
                row.names = c(NA, -9L), class = c("tbl_df", "tbl", "data.frame"))

# 处理流程
result <- df %>%
  # 将物品列转为长格式,保留发票ID
  pivot_longer(cols = -INVOICE_ID, names_to = "temp", values_to = "item") %>%
  # 过滤空值行
  filter(!is.na(item)) %>%
  # 按发票ID分组,为每个非NA物品编号
  group_by(INVOICE_ID) %>%
  mutate(item_num = paste0("Item_", row_number())) %>%
  ungroup() %>%
  # 转回宽格式,自动实现非NA值左对齐
  pivot_wider(names_from = item_num, values_from = item) %>%
  # 补充缺失的Item列,确保列数统一
  mutate(across(paste0("Item_", 1:4), ~replace_na(.x, NA))) %>%
  # 按发票ID排序(可选)
  arrange(INVOICE_ID)

# 查看结果前两行
head(result, 2)

运行后前两行结果如下:

# A tibble: 2 × 5
  INVOICE_ID Item_1 Item_2 Item_3 Item_4
       <int> <chr>  <chr>  <chr>  <lgl> 
1    7367109 Edible Vape   NA     NA    
2    7367110 Flower NA     NA     NA    

方法二:使用Base R(无需额外加载包)

直接对每行数据进行非NA值提取和补位操作:

# 原始数据同上
df <- structure(list(INVOICE_ID = 7367109:7367117, 
                     Edible = c("Edible", NA, NA, NA, NA, NA, NA, NA, "Edible"), 
                     Vape = c("Vape", NA, NA, NA, NA, NA, NA, NA, NA), 
                     Flower = c(NA, "Flower", "Flower", "Flower", "Flower", "Flower", "Flower", "Flower", "Flower"), 
                     Concentrate = c(NA, NA, NA, "Concentrate", NA, NA, NA, NA, NA)), 
                row.names = c(NA, -9L), class = c("tbl_df", "tbl", "data.frame"))

# 处理流程
# 提取物品列
items_df <- df[, -1]
# 每行非NA值左移,右侧补NA
shifted_items <- t(apply(items_df, 1, function(x) {
  c(x[!is.na(x)], rep(NA, sum(is.na(x))))
}))
# 合并发票ID和处理后的物品列,并重命名列名
result_base <- cbind(df[, "INVOICE_ID"], shifted_items)
colnames(result_base) <- c("INVOICE_ID", paste0("Item_", 1:ncol(shifted_items)))
# 转为tibble格式(可选)
result_base <- as_tibble(result_base)

# 查看结果前两行
head(result_base, 2)

两种方法均可实现需求:将每行非NA值靠左排列,NA值移至右侧,列名统一为Item_1、Item_2等。

内容的提问来源于stack exchange,提问作者hachiko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:16:14