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

在R语言中如何生成包含所有适用类别的长格式数据集?

解决方案

首先,你生成所有科目与成绩组合的代码是正确的,问题出在后续的循环处理上——每次循环都会覆盖does_not_work,最终只保留最后一次迭代的结果,而且这种多列转长的方式效率较低。下面提供两种符合需求的实现方式:

方式一:生成所有同成绩的分类组合(匹配用户示例输出)

如果需要每个学生对应所有与自己成绩相同的分类(无论分类中的科目组合是否包含该学生的科目),可以通过交叉连接实现:

library(tidyverse)

# 你的原始数据集
test <- tibble(student_id = c(1),
               subject = c("math"),
               grade_num = c(95),
               grade = c("a"))

# 生成所有科目组合(你的代码,保留不变)
all_subjects <- c("math", "science", "english")

i = 1
all_subject_combos <- c()
while(i <= length(all_subjects)) {
  if(i > 1) {
    some_combos <- combn(all_subjects, i,  FUN = function(x) paste(x, collapse = "_"), simplify = TRUE)
    all_subject_combos <- append(all_subject_combos, some_combos)
  }
  i <- i +1
}

all_grades <- c("A", "B", "C", "D", "F")

all_subjects_and_grades <- expand.grid(all_subject_combos, all_grades)

subjects_and_grades_combos <- all_subjects_and_grades %>%
  unite("names", c(Var1, Var2)) %>%
  mutate(names =  tolower(paste0("n_", str_replace_all(names, "\\|", "_")))) %>%
  pull(names)

# 把分类组合转为表格,并提取成绩部分用于匹配
category_tbl <- tibble(category = subjects_and_grades_combos) %>%
  mutate(grade = str_extract(category, "[a-z]$")) # 提取分类末尾的成绩(小写)

# 交叉连接:每个学生匹配所有同成绩的分类
result <- test %>%
  mutate(grade = tolower(grade)) %>% # 统一成绩大小写
  cross_join(category_tbl, by = "grade") %>% # 按成绩匹配所有分类
  select(student_id, subject, grade_num, grade, category)

# 查看结果
result

运行后会得到每个学生对应所有同成绩的分类行,和你提供的示例输出结构一致。

方式二:仅匹配包含学生科目+同成绩的分类

如果需要分类中的科目组合必须包含该学生的科目(比如学生学math,只保留包含math的分类+同成绩),只需在交叉连接后添加筛选:

result <- test %>%
  mutate(grade = tolower(grade)) %>%
  cross_join(category_tbl, by = "grade") %>%
  filter(str_detect(category, subject)) %>% # 筛选包含学生科目的分类
  select(student_id, subject, grade_num, grade, category)

result

为什么你的循环代码不生效?

你之前的循环每次都会重新赋值does_not_work,导致之前迭代生成的列被覆盖,最终只保留最后一次循环的列。如果一定要用循环生成多列再转长,可以这样修改,但效率不如上面的方法:

# 初始化结果为原始数据
does_not_work <- test

# 循环添加列
i = 1
while(i <= length(subjects_and_grades_combos)) {
  col_name <- paste0("subject_grade_grouping_", i)
  does_not_work <- does_not_work %>%
    mutate(!!col_name := case_when(
      # 这里可以根据需求调整匹配条件,比如同成绩+包含科目
      str_detect(subjects_and_grades_combos[i], tolower(subject)) & 
        str_detect(subjects_and_grades_combos[i], tolower(grade)) ~ subjects_and_grades_combos[i]
    ))
  i <- i +1
}

# 转长格式
long_result <- does_not_work %>%
  pivot_longer(cols = starts_with("subject_grade_grouping_"), 
               names_to = "temp", 
               values_to = "category") %>%
  drop_na(category) %>% # 去掉无匹配的分类
  select(-temp)

long_result

内容的提问来源于stack exchange,提问作者J.Sabree

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 12:51:56