使用Tidier获取DataFrame中各客户最小购买日期的报错解决
问题解决:Julia Tidier计算客户最小购买日期的两类错误
错误1:生成df_sum时的ArgumentError(参数不是排列)
错误原因
customer_id列存在缺失值,导致分组操作无法生成有效排列索引。你已过滤date的缺失值,但未处理customer_id的缺失情况,触发了DataFrames分组逻辑中的排列验证错误。
解决方法
方案1:预处理阶段过滤客户ID缺失值
在数据清洗步骤中新增对customer_id的缺失值过滤:
df = @chain df begin @select(SHOPIFY_ORDER_ID, CUSTOMER_ID, SHIPMONTH, GROSS_REVENUE, Country) @rename(order_id = SHOPIFY_ORDER_ID, customer_id = CUSTOMER_ID, date = SHIPMONTH, revenue = GROSS_REVENUE, country = Country) @filter(country != "CA") @filter(!ismissing(date)) @filter(revenue != 0.0) @filter(!ismissing(customer_id)) # 新增该行过滤客户ID缺失值 end
方案2:分组时启用缺失值跳过
在@group_by中添加skipmissing=true参数,允许分组时跳过缺失的客户ID:
df_sum = @chain df begin @group_by(customer_id, skipmissing=true) # 添加skipmissing=true @mutate( cohort = minimum(skipmissing(date)) ) end
错误2:直接调用min(df[!, :date])的MethodError
错误原因
Base的min函数仅支持单个值或多个离散值作为参数,不支持直接传入带缺失值的向量;即便你过滤了date的缺失,向量类型仍为Union{Missing, Dates.Date},触发方法匹配失败。
解决方法
方案1:使用minimum配合skipmissing
直接调用时替换为支持向量输入的minimum函数,并通过skipmissing处理潜在缺失:
minimum(skipmissing(df[!, :date]))
方案2:转换日期列类型为无缺失
在预处理阶段将date列转换为纯Dates.Date类型,彻底避免类型问题:
df = @chain df begin # 原有清洗步骤 @transform(date = convert(Vector{Dates.Date}, date)) # 转换为无缺失的日期向量 end
此时分组计算最小日期可直接使用minimum(date):
df_sum = @chain df begin @group_by(customer_id) @mutate( cohort = minimum(date) ) end
完整修正后的代码示例
using Tidier, DataFrames, Plots, CSV # 参数 f = "path" df = CSV.File(f) |> DataFrame df = @chain df begin @select(SHOPIFY_ORDER_ID, CUSTOMER_ID, SHIPMONTH, GROSS_REVENUE, Country) @rename(order_id = SHOPIFY_ORDER_ID, customer_id = CUSTOMER_ID, date = SHIPMONTH, revenue = GROSS_REVENUE, country = Country) @filter(country != "CA") @filter(!ismissing(date)) @filter(revenue != 0.0) @filter(!ismissing(customer_id)) @transform(date = convert(Vector{Dates.Date}, date)) end # 计算每个客户的最小购买日期 df_sum = @chain df begin @group_by(customer_id) @mutate( cohort = minimum(date) ) end # 验证整体最小购买日期 minimum(df[!, :date])
内容的提问来源于stack exchange,提问作者rwdvc
相关产品推荐
相关产品推荐

