R dplyr基于.vars外的列转换多列布尔值为指定区间随机日期
R数据框布尔值替换为对应行日期间随机日期解决方案
问题原因
你之前代码报错的核心原因是:transmute_at/mutate_at这类列定向操作函数默认仅能访问.vars参数指定的列,无法直接读取同数据框内未被选中的StartDate、EndDate列;同时原有写法未做按行处理,直接调用seq()会传入整列的起止日期,无法实现每行单独生成随机日期的需求。
解决方案(适配dplyr 1.0+ 官方推荐写法)
步骤1:修正示例数据语法
你提供的示例数据缺少右括号,修正后可直接运行:
library(dplyr) df <- data.frame( A = c(1,1,0,0,1), B = c(0,1,0,0,1), C = c(0,0,1,1,0), D = c(1,0,0,0,1), E = c(1,1,1,0,0), StartDate = as.Date(c("2018-03-21","1999-02-06","2004-01-19", "2000-03-18", "1998-05-20")), EndDate = as.Date(c("2020-08-02","2004-09-15","2009-07-27","2017-04-21", "2001-01-24")) )
步骤2:核心处理代码
使用rowwise()按行处理+across()定向修改前5列,可直接访问当前行的起止日期字段:
df_result <- df %>% rowwise() %>% # 开启按行计算模式 mutate( across(1:5, ~ifelse( .x == 1, sample(seq.Date(StartDate, EndDate, by = "day"), size = 1), # 取值为1时生成区间内随机日期 0 # 取值为0时保持不变 )) ) %>% ungroup() # 关闭行分组,避免影响后续数据操作
格式适配说明
由于R中同一列不能同时存储日期型和数值型数据,运行上述代码后前5列会转为数值型(日期会被转为对应的儒略日数值),如果需要和示例输出一样显示为日期字符串+0的格式,可调整代码将输出转为字符型:
df_result <- df %>% rowwise() %>% mutate( across(1:5, ~ifelse( .x == 1, as.character(sample(seq.Date(StartDate, EndDate, by = "day"), size = 1)), "0" )) ) %>% ungroup()
- 如果需要固定随机日期结果方便复现,可在运行处理代码前执行
set.seed(自定义数值),比如set.seed(123)。
旧版dplyr适配(无across函数场景)
如果你使用的是1.0版本以下的dplyr,可使用mutate_at搭配cur_data()访问全量列:
df_result <- df %>% rowwise() %>% mutate_at(1:5, ~ifelse(.x == 1, sample(seq.Date(cur_data()$StartDate, cur_data()$EndDate, by = "day"),1), 0)) %>% ungroup()
内容的提问来源于stack exchange,提问作者jp1
相关产品推荐
相关产品推荐

