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

将apply转换为purrr的pmap:求每行最新得分年份的替代实现

把apply逻辑转成purrr实现的方案

嘿,我来帮你把这段apply代码转换成更符合tidyverse风格的purrr实现~先理清楚原代码的核心逻辑:逐行找出值为1的SCORE列中最新的年份,没有匹配项就返回0,下面是两种等价的purrr写法,都能实现相同功能:

方案一:贴近原apply逻辑的pmap写法

这种写法和你原代码的思路几乎一致,只是用pmap替代了apply,更符合函数式编程的风格:

library(purrr)
library(stringr)

# 原数据
dat = data.frame('SCORE_2010'=c(0,0,1,0),
                 'SCORE_2011'=c(1,0,1,0),
                 'SCORE_2012'=c(0,0,1,0),
                 'SCORE_2013'=c(1,0,0,1))

# 先单独提取所有SCORE年份列,避免后续索引混乱
score_cols = dat |> dplyr::select(matches('^SCORE_[0-9]+'))

# 用pmap_chr逐行处理,返回字符型结果
dat$L_YEAR = pmap_chr(score_cols, function(...) {
  # 把当前行的所有值拼成向量,对应原apply里的x
  row_values = c(...)
  # 找出值为1的元素索引
  ones_positions = which(row_values == 1)
  
  if (length(ones_positions) > 0) {
    # 取最大索引(对应最新年份的列),提取列名中的年份
    latest_col = names(score_cols)[max(ones_positions)]
    str_extract(latest_col, '[0-9]+')
  } else {
    # 没有1的情况返回'0'
    '0'
  }
})

# 可选:把结果转成数值型
dat$L_YEAR = as.integer(dat$L_YEAR)

方案二:结合dplyr的更直观写法

如果习惯tidyverse的管道风格,这种写法可读性更强,不用手动处理索引,直接通过列名筛选和排序:

library(purrr)
library(stringr)
library(dplyr)

dat = data.frame('SCORE_2010'=c(0,0,1,0),
                 'SCORE_2011'=c(1,0,1,0),
                 'SCORE_2012'=c(0,0,1,0),
                 'SCORE_2013'=c(1,0,0,1))

score_cols = dat |> select(matches('^SCORE_[0-9]+'))

dat$L_YEAR = score_cols |>
  pmap(function(...) {
    # 把当前行的列名和对应值做成临时表格
    current_row = tibble(col_name = names(score_cols), value = c(...))
    # 筛选值为1的行,提取列名,取最大的(年份最新的),默认返回SCORE_0
    current_row |>
      filter(value == 1) |>
      pull(col_name) |>
      max(default = 'SCORE_0') |>
      str_extract('[0-9]+')
  }) |>
  unlist() |>
  as.integer()

小提示

原代码里有个潜在的小问题:names(dat)[max(which(x==1))]依赖于SCORE列在整个data.frame中的位置,如果后续dat新增了其他列在SCORE列前面,索引就会出错。上面的两种purrr方案都先单独提取了score_cols,避免了这个问题,更健壮。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:24:08