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

使用R的cj_tidy函数处理联合分析数据时遇行数匹配错误

问题排查:cj_tidy函数行不匹配错误

问题背景

现有数据集conjoint_data_a共100行,包含:

  • 1列ID(受访者标识)
  • 14个强制选择任务,每个任务含2个选项,每个选项有7个特征(Purpose、Flight、Econ、Civil、AI、Ally、IO),另有额外的Rating测量列,总计14×2×8=224个特征列
  • 14列选择结果变量(choice_1至choice_14)

使用cregg::cj_tidy处理数据时触发行不匹配错误,代码及错误信息如下:

原始代码

# profile_variables
list1 <- list(
Purpose = list(
~ purpose_a1 + purpose_a2 + purpose_a3 + purpose_a4 + purpose_a5 + purpose_a6 + purpose_a7 + purpose_a8 + purpose_a9 + purpose_a10 + purpose_a11 + purpose_a12 + purpose_a13 + purpose_a14,
~ purpose_b1 + purpose_b2 + purpose_b3 + purpose_b4 + purpose_b5 + purpose_b6 + purpose_b7 + purpose_b8 + purpose_b9 + purpose_b10 + purpose_b11 + purpose_b12 + purpose_b13 + purpose_b14
),
Flight = list(
~ flight_a1 + flight_a2 + flight_a3 + flight_a4 + flight_a5 + flight_a6 + flight_a7 + flight_a8 + flight_a9 + flight_a10 + flight_a11 + flight_a12 + flight_a13 + flight_a14,
~ flight_b1 + flight_b2 + flight_b3 + flight_b4 + flight_b5 + flight_b6 + flight_b7 + flight_b8 + flight_b9 + flight_b10 + flight_b11 + flight_b12 + flight_b13 + flight_b14
),
Econ = list(
~ econ_a1 + econ_a2 + econ_a3 + econ_a4 + econ_a5 + econ_a6 + econ_a7 + econ_a8 + econ_a9 + econ_a10 + econ_a11 + econ_a12 + econ_a13 + econ_a14,
~ econ_b1 + econ_b2 + econ_b3 + econ_b4 + econ_b5 + econ_b6 + econ_b7 + econ_b8 + econ_b9 + econ_b10 + econ_b11 + econ_b12 + econ_b13 + econ_b14
),
Civil = list(
~ civil_a1 + civil_a2 + civil_a3 + civil_a4 + civil_a5 + civil_a6 + civil_a7 + civil_a8 + civil_a9 + civil_a10 + civil_a11 + civil_a12 + civil_a13 + civil_a14,
~ civil_b1 + civil_b2 + civil_b3 + civil_b4 + civil_b5 + civil_b6 + civil_b7 + civil_b8 + civil_b9 + civil_b10 + civil_b11 + civil_b12 + civil_b13 + civil_b14
),
AI = list(
~ ai_a1 + ai_a2 + ai_a3 + ai_a4 + ai_a5 + ai_a6 + ai_a7 + ai_a8 + ai_a9 + ai_a10 + ai_a11 + ai_a12 + ai_a13 + ai_a14,
~ ai_b1 + ai_b2 + ai_b3 + ai_b4 + ai_b5 + ai_b6 + ai_b7 + ai_b8 + ai_b9 + ai_b10 + ai_b11 + ai_b12 + ai_b13 + ai_b14
),
Ally = list(
~ ally_a1 + ally_a2 + ally_a3 + ally_a4 + ally_a5 + ally_a6 + ally_a7 + ally_a8 + ally_a9 + ally_a10 + ally_a11 + ally_a12 + ally_a13 + ally_a14,
~ ally_b1 + ally_b2 + ally_b3 + ally_b4 + ally_b5 + ally_b6 + ally_b7 + ally_b8 + ally_b9 + ally_b10 + ally_b11 + ally_b12 + ally_b13 + ally_b14
),
IO = list(
~ io_a1 + io_a2 + io_a3 + io_a4 + io_a5 + io_a6 + io_a7 + io_a8 + io_a9 + io_a10 + io_a11 + io_a12 + io_a13 + io_a14,
~ io_b1 + io_b2 + io_b3 + io_b4 + io_b5 + io_b6 + io_b7 + io_b8 + io_b9 + io_b10 + io_b11 + io_b12 + io_b13 + io_b14
),
Rating = list(
~ rating_a1 + rating_a2 + rating_a3 + rating_a4 + rating_a5 + rating_a6 + rating_a7 + rating_a8 + rating_a9 + rating_a10 + rating_a11 + rating_a12 + rating_a13 + rating_a14,
~ rating_b1 + rating_b2 + rating_b3 + rating_b4 + rating_b5 + rating_b6 + io_b7 + rating_b8 + rating_b9 + rating_b10 + rating_b11 + rating_b12 + rating_b13 + rating_b14
)
)

# task variables
list2 <- list(choice = ~ choice_1 + choice_2 + choice_3 + choice_4 + choice_5 + choice_6 + choice_7+ choice_8 + choice_9 + choice_10 + choice_11 + choice_12 + choice_13 + choice_14)

reintegration.data <- cj_tidy(conjoint_data_a, profile_variables = list1, task_variables = list2, id = ~ Respondent)

错误信息

在`[[<-`中:
! 分配的数据`halfstack[[names(task_variables)[i]]]`必须与现有数据兼容。
✖ 现有数据有14行。
✖ 分配的数据有100行。
ℹ 仅大小为1的向量可被循环利用。
由`vectbl_recycle_rhs_rows()`中的错误导致:
! 无法将大小为100的输入循环利用为大小14。

验证代码结果

执行以下验证代码后,所有结果返回FALSE:

lengths_list1 <- sapply(list1, function(x) length(unlist(x)) == n_rows)
lengths_list2 <- sapply(list2, function(x) length(unlist(x)) == n_rows)

print(lengths_list1)
print(lengths_list2)

错误根源分析

  1. profile_variables结构错误:cj_tidy要求每个属性的子列表元素是对应每个任务中两个选项的列名集合,而非用公式将所有任务的列相加。公式中的+会被解析为变量运算,而非列名列表,导致列映射逻辑混乱。
  2. 笔误问题:Rating子列表的第二个元素中,io_b7应为rating_b7,属于列名错误。
  3. ID参数不匹配:数据集的标识列为ID,但代码中id = ~ Respondent与实际列名不符。
  4. 验证代码逻辑错误:n_rows未定义,导致比较逻辑失效,返回全FALSE。

解决方案

1. 修正profile_variables构造

改用字符向量指定列名,避免公式解析错误。每个属性的两个子元素分别对应14个任务的a、b选项列:

# 生成任务序号
task_nums <- 1:14

# 构造profile_variables
list1 <- list(
  Purpose = list(
    paste0("purpose_a", task_nums),
    paste0("purpose_b", task_nums)
  ),
  Flight = list(
    paste0("flight_a", task_nums),
    paste0("flight_b", task_nums)
  ),
  Econ = list(
    paste0("econ_a", task_nums),
    paste0("econ_b", task_nums)
  ),
  Civil = list(
    paste0("civil_a", task_nums),
    paste0("civil_b", task_nums)
  ),
  AI = list(
    paste0("ai_a", task_nums),
    paste0("ai_b", task_nums)
  ),
  Ally = list(
    paste0("ally_a", task_nums),
    paste0("ally_b", task_nums)
  ),
  IO = list(
    paste0("io_a", task_nums),
    paste0("io_b", task_nums)
  ),
  Rating = list(
    paste0("rating_a", task_nums),
    paste0("rating_b", task_nums)
  )
)

2. 修正task_variables与ID参数

确保任务变量列名正确,ID参数匹配数据集列名:

list2 <- list(choice = paste0("choice_", task_nums))

# 调用cj_tidy,修正id参数
reintegration.data <- cj_tidy(
  conjoint_data_a,
  profile_variables = list1,
  task_variables = list2,
  id = ~ ID
)

3. 修正验证代码

定义n_rows为任务数量(14),验证每个属性的列数是否匹配:

n_rows <- 14
lengths_list1 <- sapply(list1, function(x) all(sapply(x, length) == n_rows))
lengths_list2 <- sapply(list2, function(x) length(x) == n_rows)

print(lengths_list1)
print(lengths_list2)

关键说明

  • cj_tidy会将每个受访者的每个任务的两个选项展开为单独行,最终输出行数应为100(受访者)×14(任务)×2(选项)=2800行。
  • 任务变量(如choice)会自动与对应任务的两个选项行匹配,无需手动重复处理。

内容的提问来源于stack exchange,提问作者Shown

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:54:55