如何让dplyr::cur_group_id()按数据出现顺序而非字母序生成组编号
问题原因
cur_group_id() 生成的分组编号默认基于分组变量的词典序排序结果,group_by(i) 会自动将项目i按i1、i2、i3的字母顺序排列后再编号,不会保留每个被试数据里项目的原始出现顺序,因此会出现编号错位。
推荐解决方案
直接使用dplyr内置的consecutive_id()函数即可,该函数会按变量在数据中出现的连续顺序生成编号,仅需按被试p分组后计算,不需要拆分数据集做循环映射,代码最简洁:
library(tidyverse) result <- data |> group_by(p) |> mutate(trial_order = consecutive_id(i)) |> ungroup()
运行上述代码得到的结果完全匹配预期输出:同一被试下,第一次出现的项目对应试次顺序为1,后续新出现的项目顺序号依次递增,同一项目的所有行编号一致。
旧版本dplyr兼容方案
如果使用的dplyr版本没有consecutive_id()函数,可以先将项目列i转换为因子,因子水平按每个被试下i的首次出现顺序设置,再生成分组编号即可:
result <- data |> group_by(p) |> mutate( i = factor(i, levels = unique(i)), trial_order = cur_group_id() ) |> ungroup() |> # 不需要保留因子类型的话可以转回字符 mutate(i = as.character(i))
原有代码的修正方式
你之前使用group_split()+purrr::map_df()的写法,只需要在分组前先将i转为按首次出现顺序设置水平的因子,即可得到正确结果,不过该写法冗余度更高,不推荐使用:
data |> group_split(p) |> purrr::map_df( ~ .x |> mutate(i = factor(i, levels = unique(i))) |> group_by(i) |> mutate(trial_order = cur_group_id()) )
内容的提问来源于stack exchange,提问作者Carlos Luis Rivera
相关产品推荐
相关产品推荐

