使用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)
错误根源分析
- profile_variables结构错误:
cj_tidy要求每个属性的子列表元素是对应每个任务中两个选项的列名集合,而非用公式将所有任务的列相加。公式中的+会被解析为变量运算,而非列名列表,导致列映射逻辑混乱。 - 笔误问题:
Rating子列表的第二个元素中,io_b7应为rating_b7,属于列名错误。 - ID参数不匹配:数据集的标识列为
ID,但代码中id = ~ Respondent与实际列名不符。 - 验证代码逻辑错误:
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
相关产品推荐
相关产品推荐

