如何在R中获取前一行order最后字符及dur_列最后非负值
R语言实现DataFrame新增指定列需求
问题背景
现有如下DataFrame:
d <- data.frame(order = c("101", "01", "10", "01", "101"), dur_1 = c(50, 20, 40, 25, 45), dur_2 = c(40, 30, 45, 34, 96), dur_3 = c(20, 0, 0, 0, 125))
需要新增两列pre_order和pre_dur,规则如下:
- pre_order:取前一行
order列的最后一个字符,第一行值为NA - pre_dur:取前一行所有以
dur_开头的列中最后一个非0值(支持任意数量的dur_系列列),第一行值为NA
期望输出结果:
d1 <- data.frame(order=c("101","01","10","01","101"), dur_1=c(50,20,40,25,45), dur_2=c(40,30,45,34,96), dur_3=c(20,0,0,0,125), pre_order=c(NA,1,1,0,1), pre_dur=c(NA,20,30,45,34))
解决方案
方法一:Base R实现
无需额外安装包,直接用基础R函数完成:
# 提取所有以dur_开头的列名 dur_cols <- grep("^dur_", names(d), value = TRUE) # 计算每行dur_列的最后一个非0值 last_non_zero_dur <- apply(d[dur_cols], 1, function(x) { rev_x <- rev(x) # 从后往前找第一个非0值的位置 first_non_zero_idx <- which(rev_x != 0)[1] # 若没有非0值则返回NA,否则返回对应值 ifelse(is.na(first_non_zero_idx), NA, rev_x[first_non_zero_idx]) }) # 生成pre_order列:取前一行order的最后一个字符并转为数值 d$pre_order <- c(NA, as.numeric(substr(d$order[-nrow(d)], nchar(d$order[-nrow(d)]), nchar(d$order[-nrow(d)])))) # 生成pre_dur列:取前一行的last_non_zero_dur值 d$pre_dur <- c(NA, last_non_zero_dur[-nrow(d)]) # 查看最终结果 print(d)
方法二:Tidyverse工具包实现
使用dplyr和tidyr的管道式操作,代码更清晰易读:
library(dplyr) library(tidyr) d_result <- d %>% # 按行处理,计算每行的最后一个非0dur值 rowwise() %>% mutate(temp_dur = { # 获取当前行所有dur_开头的列值 dur_vals <- c_across(starts_with("dur_")) rev_vals <- rev(dur_vals) first_non_zero_idx <- which(rev_vals != 0)[1] ifelse(is.na(first_non_zero_idx), NA, rev_vals[first_non_zero_idx]) }) %>% ungroup() %>% # 生成pre_order和pre_dur:用lag()函数取前一行的值 mutate( pre_order = lag(as.numeric(substr(order, nchar(order), nchar(order)))), pre_dur = lag(temp_dur) ) %>% # 移除临时计算列 select(-temp_dur) # 查看最终结果 print(d_result)
两种方法执行后,都能得到与期望一致的DataFrame。
内容的提问来源于stack exchange,提问作者Lee
相关产品推荐
相关产品推荐

