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

如何在R中将因子级别转为列、列转为因子级别(排序数据场景)

问题描述

我有一份关于博士就读动机排序的数据集,示例数据的R创建代码如下:

df <- data.frame(
  id = c(1:4),
  rank1 = c("Salary", "Interest", "Career", "Title"),
  rank2 = c("Title", "Career", "Salary", NA),
  rank3 = c("Interest", "Title", NA, NA),
  rank4 = c("Career", NA, NA, NA))

# 查看数据
df

输出结果:

id    rank1  rank2    rank3  rank4
1  1   Salary  Title Interest Career
2  2 Interest Career    Title   <NA>
3  3   Career Salary     <NA>   <NA>
4  4    Title   <NA>     <NA>   <NA>

其中id为1的受访者将"Salary"列为最重要动机,其次是"Title"等。我需要将原数据的因子级别(如Salary)转为列,原列名(如rank1)转为因子值,得到如下目标格式:

id Salary Title Interest Career
1  1  rank1 rank2    rank3  rank4
2  2   <NA> rank3    rank1  rank2
3  3  rank2  <NA>     <NA>  rank1
4  4   <NA> rank1     <NA>   <NA>

我已尝试tidyr包的spread()函数,但未达到预期效果,请问如何在R中实现该转换?


解决方案

你可以通过先转长格式、再转宽格式的方式实现,使用tidyr包的pivot_longer()和pivot_wider()函数(这两个是spread()的替代函数,功能更灵活):

步骤1:加载依赖包

library(tidyr)
library(dplyr) # 用于管道操作,简化代码

步骤2:执行数据转换

result <- df %>%
  # 将rank1-rank4列转为长格式,保留id列,过滤空值
  pivot_longer(
    cols = starts_with("rank"),
    names_to = "rank_level",
    values_to = "motivation",
    values_drop_na = TRUE
  ) %>%
  # 将动机转为列,排序等级作为对应值
  pivot_wider(
    names_from = motivation,
    values_from = rank_level
  )

# 查看转换结果
result

输出结果

# A tibble: 4 × 5
     id Salary Title  Interest Career
  <int> <chr>  <chr>  <chr>    <chr> 
1     1 rank1  rank2  rank3    rank4 
2     2 NA     rank3  rank1    rank2 
3     3 rank2  NA     NA       rank1 
4     4 NA     rank1  NA       NA    

关键说明

  1. pivot_longer():把原数据中rank1到rank4的宽格式列“拉长”,每一行对应一个受访者的一条动机排序记录,同时通过values_drop_na = TRUE过滤空值,避免后续转换产生无效行。
  2. pivot_wider():将长格式中的motivation列的唯一值(Salary、Title等)转为新列,对应的rank_level(rank1、rank2等)作为列值,自动匹配每个id的排序信息,缺失位置填充NA。

如果需要将结果转为普通数据框格式,可执行as.data.frame(result)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:05:33