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

如何在R中基于多条件按客户级创建DEFAULT_DATE列?

在R语言中按客户级别生成最早违约日期列的实现方案

先明确你的需求:基于客户分组,给每个客户的所有贷款记录添加DEFAULT_DATE列——如果客户有至少一笔违约贷款,就取该客户最早的违约日期;如果没有违约,就填-。

原始数据集

CUSTOMER LOAN DATE LOAN_DEFAULT CUSTOMER_DEFAULT
1 101 201601 Y Y
1 102 201603 N Y
1 101 201501 Y Y
2 201 201601 N N
2 202 201603 N N

预期输出

CUSTOMER LOAN DATE LOAN_DEFAULT CUSTOMER_DEFAULT DEFAULT_DATE
1 101 201601 Y Y 201501
1 102 201603 N Y 201501
1 103 201501 Y Y 201501
2 201 201601 N N -
2 202 201603 N N -

下面是两种实用的实现方式:


方法一:使用dplyr(tidyverse风格)

这是数据处理中最常用的方式,代码可读性高,逻辑清晰:

# 先安装并加载dplyr包(如果还没安装的话)
# install.packages("dplyr")
library(dplyr)

# 第一步:构造你的原始数据集
df <- data.frame(
  CUSTOMER = c(1, 1, 1, 2, 2),
  LOAN = c(101, 102, 101, 201, 202),
  DATE = c(201601, 201603, 201501, 201601, 201603),
  LOAN_DEFAULT = c("Y", "N", "Y", "N", "N"),
  CUSTOMER_DEFAULT = c("Y", "Y", "Y", "N", "N"),
  stringsAsFactors = FALSE
)

# 第二步:分组计算并生成新列
df_result <- df %>%
  group_by(CUSTOMER) %>%  # 按客户ID分组
  mutate(
    DEFAULT_DATE = ifelse(
      any(LOAN_DEFAULT == "Y"),  # 判断当前客户是否有违约记录
      min(DATE[LOAN_DEFAULT == "Y"]),  # 取该客户最早的违约日期
      "-"  # 无违约则填"-"
    )
  ) %>%
  ungroup()  # 取消分组,回到普通数据框

# 查看最终结果
print(df_result)

代码说明:

  • group_by(CUSTOMER):把数据按客户分组,后续的计算都在客户内部进行
  • any(LOAN_DEFAULT == "Y"):快速判断客户是否存在违约贷款
  • DATE[LOAN_DEFAULT == "Y"]:筛选出当前客户所有违约贷款的日期,再用min()取最早的那个
  • 最后用ungroup()取消分组,避免后续操作受分组影响

方法二:基础R实现

如果不想加载额外包,用基础R的ave()函数也能实现:

# 构造原始数据集(和上面一致)
df <- data.frame(
  CUSTOMER = c(1, 1, 1, 2, 2),
  LOAN = c(101, 102, 101, 201, 202),
  DATE = c(201601, 201603, 201501, 201601, 201603),
  LOAN_DEFAULT = c("Y", "N", "Y", "N", "N"),
  CUSTOMER_DEFAULT = c("Y", "Y", "Y", "N", "N"),
  stringsAsFactors = FALSE
)

# 直接生成DEFAULT_DATE列
df$DEFAULT_DATE <- with(df, ave(
  DATE,
  CUSTOMER,
  FUN = function(x) {
    # 获取当前客户对应的所有违约标记
    current_cust <- unique(CUSTOMER)
    default_flags <- LOAN_DEFAULT[CUSTOMER == current_cust]
    # 筛选违约日期
    default_dates <- x[default_flags == "Y"]
    # 判断并返回结果
    if (length(default_dates) > 0) {
      as.character(min(default_dates))  # 转成字符型和"-"统一类型
    } else {
      "-"
    }
  }
))

# 查看结果
print(df)

代码说明:

  • ave()函数可以按指定分组(这里是CUSTOMER)对目标列(这里是DATE)应用自定义函数
  • 自定义函数里先筛选当前客户的违约标记,再提取对应的日期,最后判断是否有违约日期并返回对应结果

两种方法都能得到你想要的预期输出,推荐用dplyr的方式,代码更简洁易读,后续维护也方便。

内容的提问来源于stack exchange,提问作者S.Lee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 12:47:40