如何用循环为R数据框批量添加分组排序后的lead分类列?
批量生成按id分组的lead衍生列
我有一个包含date、id、category列的数据框,想要批量添加category1、category2…这类列,每一列对应每个id按date排序后category的lead值(n分别取1、2、3……)。目前手动实现的非循环代码如下:
df <- df %>% dplyr::group_by(id) %>% dplyr::mutate(category1 = dplyr::lead(category, n = 1L, order_by = date)) df <- df %>% dplyr::group_by(id) %>% dplyr::mutate(category2 = dplyr::lead(category, n = 2L, order_by = date)) df <- df %>% dplyr::group_by(id) %>% dplyr::mutate(category3 = dplyr::lead(category, n = 3L, order_by = date)) #and so on.
最佳实现方式
方法1:用dplyr的across批量生成(推荐,tidyverse风格)
这种方法无需显式循环,直接通过across批量处理多个lead值,代码更简洁高效:
# 定义需要生成的lead次数,比如生成3列就设为3 n_max <- 3 df <- df %>% dplyr::group_by(id) %>% # 先按date排序,确保lead顺序正确 dplyr::arrange(date, .by_group = TRUE) %>% dplyr::mutate( # 遍历1到n_max,生成对应的category列 across(1:n_max, ~dplyr::lead(category, n = .x), .names = "category{.x}") ) %>% dplyr::ungroup()
方法2:传统for循环实现
如果你更习惯显式循环的写法,可以用以下方式:
n_max <- 3 # 先统一按id和date排序,避免重复排序 df <- df %>% dplyr::group_by(id) %>% dplyr::arrange(date, .by_group = TRUE) %>% dplyr::ungroup() # 循环生成每一列 for (i in 1:n_max) { col_name <- paste0("category", i) df[[col_name]] <- df %>% dplyr::group_by(id) %>% dplyr::mutate(temp = dplyr::lead(category, n = i)) %>% dplyr::pull(temp) }
说明
两种方法都需要先确保每个id组内的date是有序的,这样lead函数才能正确取到后续行的category值。第一种across的方式更符合tidyverse的编程习惯,代码更紧凑,推荐使用。
内容的提问来源于stack exchange,提问作者Gosha K
相关产品推荐
相关产品推荐

