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

使用R语言dplyr按列计算行分位数/十分位数并插入新列

解决方案

一、核心问题分析

你之前的quantile代码无法运行,是因为across要求传入的是对列中每个元素进行映射的函数,而quantile()本身是返回整列的分位数断点值,不是给每个元素分配对应的分位数组。同时直接用列名切片c(cnam_year2[1]:cnam_year2[length(cnam_year2)])不够安全,建议改用all_of()来引用字符向量中的列名。


二、生成并插入分位数(十分位数)列

方法1:基于分位数断点分组(更贴合统计意义的十分位数)

这种方法会根据每列的实际分位数断点,将每个值分配到对应的十分位组(1-10),自动忽略NA值:

library(dplyr)
library(purrr) # 用于后续列排序

# 生成带十分位数列的数据框
decile_result <- yearRetsMSA2 %>%
  mutate(
    across(
      all_of(cnam_year2),
      ~ cut(
        .,
        breaks = quantile(., na.rm = TRUE, probs = seq(0, 1, 0.1)),
        labels = 1:10,
        include.lowest = TRUE
      ),
      .names = "{.col}_decile" # 新列命名规则:原列名_decile
    )
  )

# 重新排列列,让原年份列和对应的十分位数列相邻
new_col_order <- unlist(purrr::map(cnam_year2, ~ c(.x, paste0(.x, "_decile"))))
decile_result_reordered <- decile_result %>% select(all_of(new_col_order))

方法2:基于数据量均分(等数量分组)

如果需要严格将非NA值均分为10组,可使用ntile():

decile_result <- yearRetsMSA2 %>%
  mutate(
    across(
      all_of(cnam_year2),
      ~ ntile(na.omit(.), 10)[match(., na.omit(.))], # 保留NA位置
      .names = "{.col}_decile"
    )
  )

# 同方法1的列排序步骤
new_col_order <- unlist(purrr::map(cnam_year2, ~ c(.x, paste0(.x, "_decile"))))
decile_result_reordered <- decile_result %>% select(all_of(new_col_order))

三、生成并插入排名列

基于你原有的排名代码,优化NA处理和列排序逻辑,确保排名列紧跟对应年份列:

rank_result <- yearRetsMSA2 %>%
  mutate(
    across(
      all_of(cnam_year2),
      ~ rank(., na.last = "keep"), # 保留NA的原始位置,不参与排名
      .names = "{.col}_rank" # 新列命名规则:原列名_rank
    )
  )

# 重新排列列,让原年份列和对应的排名列相邻
rank_col_order <- unlist(purrr::map(cnam_year2, ~ c(.x, paste0(.x, "_rank"))))
rank_result_reordered <- rank_result %>% select(all_of(rank_col_order))

四、同时生成排名+分位数列

如果需要一次性生成两种衍生列并保持相邻结构:

combined_result <- yearRetsMSA2 %>%
  mutate(
    # 生成排名列
    across(
      all_of(cnam_year2),
      ~ rank(., na.last = "keep"),
      .names = "{.col}_rank"
    ),
    # 生成十分位数列
    across(
      all_of(cnam_year2),
      ~ cut(
        .,
        breaks = quantile(., na.rm = TRUE, probs = seq(0, 1, 0.1)),
        labels = 1:10,
        include.lowest = TRUE
      ),
      .names = "{.col}_decile"
    )
  )

# 排列列顺序:原年份列 → 排名列 → 十分位数列
combined_col_order <- unlist(purrr::map(cnam_year2, ~ c(.x, paste0(.x, "_rank"), paste0(.x, "_decile"))))
combined_result_reordered <- combined_result %>% select(all_of(combined_col_order))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:07:48