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

如何在R的tidyverse中用mutate_at将多列分为4个近似等规模有序组?

解决方案

要实现多分数列的近似等规模分组,核心是替换cut_number为ntile函数——ntile不依赖足够多的唯一值,而是直接按排序后的观测位置分配组,能保证每组数量尽可能均等,同时避免报错。以下是两种适配不同需求的实现方式:

方式1:强制分组(所有场景生效)

直接使用ntile对每列进行4组划分,即使存在大量重复值(如scores_2的多个0)也能生成近似等规模的组:

library(tidyverse)

dat <- data.frame(Suburb = c("Werribee", "Hoppers", "Carlton", "North", "Serrano", "Upwell","Market", "Poynton", "Stawell"),
                  scores_1 = c(0,0.0001, 230, 340, 340, 10, 3490, 5,21),
                  scores_2 = c(12, 0,0,0,0,0,0, 45,13),
                  scores_3 = c(4,5,6,7,8,9,10, 45, 45))

allscores <- c("scores_1", "scores_2", "scores_3")

# 使用mutate across替代已软弃用的mutate_at
myresult <- dat %>% 
  mutate(across(all_of(allscores), 
                list(risk_levels = ~ ntile(., n = 4)),
                .names = "{.col}_risk_levels"))

说明

  • ntile(x, n = 4)会将排序后的观测值划分为4组,每组数量差异不超过1:比如9条数据会分成3、2、2、2的规模。
  • 分组逻辑为分数越低,风险等级(组号)越小,若需要反向(分数越高等级越高),可改用ntile(desc(x), n = 4)。

方式2:仅在有效场景分组(大量0值场景返回NA)

如果希望在唯一值不足4个的场景下不生成分组(返回NA),可以自定义函数先做判断:

assign_risk <- function(x, n = 4) {
  # 当唯一值数量小于分组数时返回NA,否则用ntile分组
  if (n_distinct(x) < n) {
    rep(NA_integer_, length(x))
  } else {
    ntile(x, n)
  }
}

myresult <- dat %>% 
  mutate(across(all_of(allscores), 
                list(risk_levels = assign_risk),
                .names = "{.col}_risk_levels"))

说明

  • n_distinct(x)用于统计列的唯一值数量,若小于4则返回NA向量,避免无意义的分组。
  • 示例中scores_2有4个唯一值(0、12、13、45),会正常生成分组;若某列只有2个唯一值,该列的风险等级列会全为NA。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 12:21:06