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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:57:41