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

R data.table试次刺激历史标记、编码及匹配校验实现咨询

原有代码错误原因

你写的自定义函数h存在两个核心逻辑问题:

  1. 只取了匹配刺激的行号,没有取列标识——which(..., arr.ind = TRUE)返回的col列值为1代表刺激出现在Chosen列,为2代表出现在Rejected列,你完全没用到这个信息,自然无法判断上次是选中还是拒绝
  2. 返回值错误:你赋值给stim_chosen[k]的是当前stim向量对应行的值,不是「Chosen/Rejected」的状态标识,所以结果完全不符合需求
    而且这种逐次用which遍历的方式时间复杂度是O(n²),数据量一大不仅慢,还容易出索引错误。

正确实现方案

用data.table逐行更新状态字典的方式实现,时间复杂度只有O(n),大样本下效率高也不会出错,完整可运行代码如下:

library(data.table)

# 样例数据,可替换为你的实际数据
df <- data.table(
  stim1 = c(2,1,2,1,3),
  stim2 = c(3,3,1,2,1),
  Chosen = c(2,3,1,1,3),
  Rejected = c(3,1,2,2,1),
  outcome = c(1,1,1,0,1)
)

# 初始化状态字典,存储每个刺激的最近信息:状态(Chosen/Rejected)、对应outcome、上次配对的选中刺激
stim_state <- list()

# 预生成需要的列
df[, `:=`(
  Previous_stim1 = NA_character_,
  Previous_stim2 = NA_character_,
  Left_type = NA_real_,
  right_type = NA_real_,
  Current_alternative_left = NA_real_,
  Current_alternative_right = NA_real_
)]

# 逐行处理更新
for (i in 1:nrow(df)) {
  s1 <- df$stim1[i]
  s2 <- df$stim2[i]
  chosen <- df$Chosen[i]
  rejected <- df$Rejected[i]
  oc <- df$outcome[i]
  
  # 填充stim1对应的所有列
  s1_key <- as.character(s1)
  if (s1_key %in% names(stim_state)) {
    s1_info <- stim_state[[s1_key]]
    df$Previous_stim1[i] <- s1_info$state
    # 按规则编码Left_type
    if (s1_info$state == "Chosen") {
      df$Left_type[i] <- ifelse(s1_info$outcome == 1, 1, 2)
    } else {
      df$Left_type[i] <- ifelse(s1_info$outcome == 1, 3, 4)
    }
    # 校验配对的选中刺激是否一致
    df$Current_alternative_left[i] <- as.integer(s1_info$paired_chosen == s2)
  }
  
  # 填充stim2对应的所有列
  s2_key <- as.character(s2)
  if (s2_key %in% names(stim_state)) {
    s2_info <- stim_state[[s2_key]]
    df$Previous_stim2[i] <- s2_info$state
    # 按规则编码right_type
    if (s2_info$state == "Chosen") {
      df$right_type[i] <- ifelse(s2_info$outcome == 1, 1, 2)
    } else {
      df$right_type[i] <- ifelse(s2_info$outcome == 1, 3, 4)
    }
    # 校验配对的选中刺激是否一致
    df$Current_alternative_right[i] <- as.integer(s2_info$paired_chosen == s1)
  }
  
  # 更新当前试次两个刺激的状态
  stim_state[[as.character(chosen)]] <- list(
    state = "Chosen",
    outcome = oc,
    paired_chosen = chosen
  )
  stim_state[[as.character(rejected)]] <- list(
    state = "Rejected",
    outcome = oc,
    paired_chosen = chosen
  )
}

# 输出结果查看
print(df)

如果只需要第一步的Previous_stim1/2列,删除后续类型编码、校验相关的代码即可,逻辑通用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 09:18:00