R语言中银行交易时间24小时分箱及客户交易频次统计需求
解决银行交易数据按小时区间分组并统计客户交易频次的问题
嘿,我来帮你搞定这个交易时间分组的问题!你之前用as.POSIXct没得到预期结果,大概率是因为这个函数会自动补全日期,而你其实只需要提取小时部分就行。而且嵌套24层ifelse太麻烦了,咱们用更简洁易维护的方法来实现你的需求:
步骤1:正确提取交易时间的小时部分
首先咱们要把字符型的交易时间转换成时间格式,然后提取出小时数(0-23的整数)。这里推荐用lubridate包的hms()函数,专门处理时分秒格式的字符串:
# 先加载tidyverse(包含lubridate和dplyr,方便后续操作) library(tidyverse) # 转换时间并提取小时 Customers <- Customers %>% mutate( # 把TRANSACTION.TIME转换成时分秒对象 transaction_time = hms(TRANSACTION.TIME), # 提取小时数(范围0-23) hour_of_day = hour(transaction_time) )
如果不想加载额外包,用基础R也能实现:
# 基础R方法 Customers$transaction_time <- strptime(Customers$TRANSACTION.TIME, format = "%H:%M:%S") # 提取小时并转成整数 Customers$hour_of_day <- as.integer(format(Customers$transaction_time, "%H"))
步骤2:给每个小时区间分配箱号
按照你的要求:8-9点为箱号1,9-10点为箱号2,……,7-8点为箱号24。咱们可以用简单的条件判断或者数学计算来实现,完全不用嵌套24层ifelse:
方法1:用dplyr的case_when(可读性强)
Customers <- Customers %>% mutate( timebins = case_when( # 8点及以后的小时,箱号=小时数-7(8-7=1,9-7=2……23-7=16) hour_of_day >= 8 ~ hour_of_day - 7, # 0-7点的小时,箱号=小时数+17(0+17=17,1+17=18……7+17=24) TRUE ~ hour_of_day + 17 ) )
方法2:用基础R的ifelse(更简洁)
Customers$timebins <- ifelse(Customers$hour_of_day >= 8, Customers$hour_of_day - 7, Customers$hour_of_day + 17)
步骤3:统计每位客户各时段的交易频次
现在咱们可以统计每个客户在每个时段的交易次数,有两种常用方式:
方式1:长格式统计(适合后续分析)
# 统计每个客户每个时段的交易次数 customer_time_counts <- Customers %>% count(CUSTOMER_ID, timebins, name = "transaction_count")
方式2:宽格式统计(方便查看所有时段)
如果想把每个时段作为一列展示,用pivot_wider:
customer_time_counts_wide <- Customers %>% count(CUSTOMER_ID, timebins, name = "transaction_count") %>% pivot_wider( names_from = timebins, values_from = transaction_count, values_fill = 0 # 没有交易的时段填0 )
如果用基础R,直接用table()函数:
# 生成交叉表 customer_counts_table <- table(Customers$CUSTOMER_ID, Customers$timebins) # 转成数据框方便查看 customer_counts_df <- as.data.frame.matrix(customer_counts_table)
关于你之前的as.POSIXct问题
你之前用as.POSIXct(Customers$TRANSACTION.TIME,format="%H:%M:%S")得到的结果不符合预期,是因为as.POSIXct会自动把当前系统日期补全到时间前面,生成类似"2024-05-20 08:30:15"的完整时间对象,而你需要的只是小时部分,所以直接提取小时数就可以啦。
内容的提问来源于stack exchange,提问作者Anadil
相关产品推荐
相关产品推荐

