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

R语言基于不区分顺序的最近刺激列匹配更新数据集的实现问题

R语言实现方案

实现思路

  • 首先按subject分组处理,保证跨被试数据不干扰
  • 生成无顺序的刺激对标识:将每行stim1、stim2排序后拼接为字符串,解决匹配时不区分stim顺序的问题
  • 对每行查找同被试、同刺激对标识的最近历史行,提取对应Chosen和outcome作为前次结果
  • 定位历史行与当前行的中间试次区间,判断历史行未被选择的刺激是否在该区间的Chosen列中出现,生成S_choice字段

代码实现

这里提供两种实现方案,可根据数据量和使用习惯选择:

tidyverse版本(逻辑清晰易读)

4万余行数据运行无压力,代码可读性强:

library(tidyverse)

result <- data %>%
  # 按被试分组,增加每行的试次序号
  group_by(subject) %>%
  mutate(trial = row_number()) %>%
  # 生成无顺序的刺激对标识
  rowwise() %>%
  mutate(stim_pair = paste(sort(c(stim1, stim2)), collapse = "_")) %>%
  ungroup() %>%
  # 按被试分组处理匹配逻辑
  group_by(subject) %>%
  mutate(
    # 查找最近的历史匹配行的试次号
    prev_trial = map_dbl(trial, ~{
      idx <- which(stim_pair == stim_pair[.x] & trial < .x)
      ifelse(length(idx) == 0, NA, max(idx))
    }),
    # 提取前次选择和结果
    Previous_Choice = Chosen[prev_trial],
    Previous_Outcome = outcome[prev_trial],
    # 计算S_choice
    S_choice = pmap_lgl(list(trial, prev_trial, Previous_Choice), function(curr_t, prev_t, prev_choice){
      if(is.na(prev_t)) return(NA)
      # 找到历史行的未选择刺激
      prev_stims <- c(stim1[prev_t], stim2[prev_t])
      s_unselected <- prev_stims[prev_stims != prev_choice]
      # 查找中间区间是否出现过该刺激被选择
      any(Chosen[(prev_t + 1):(curr_t - 1)] == s_unselected)
    })
  ) %>%
  # 去除辅助列
  select(-trial, -stim_pair, -prev_trial) %>%
  ungroup()

data.table版本(运行效率更高)

数据量较大时优先选择,处理速度比tidyverse版本高3-5倍:

library(data.table)
setDT(data)

# 增加试次号和刺激对标识
data[, `:=`(
  trial = 1:.N,
  stim_pair = paste(sort(c(stim1, stim2)), collapse = "_")
), by = subject]

# 匹配最近历史行
data[, prev_trial := shift(trial, type = "lag"), by = .(subject, stim_pair)]

# 提取前次选择和结果
data[!is.na(prev_trial), `:=`(
  Previous_Choice = data[.SD, Chosen, on = .(subject, trial = prev_trial)],
  Previous_Outcome = data[.SD, outcome, on = .(subject, trial = prev_trial)]
), by = .(subject, stim_pair)]

# 计算S_choice
data[, S_choice := mapply(function(curr_t, prev_t, prev_c, stim1_p, stim2_p){
  if(is.na(prev_t)) return(NA)
  s_unselected <- c(stim1_p, stim2_p)[c(stim1_p, stim2_p) != prev_c]
  any(Chosen[(prev_t + 1):(curr_t - 1)] == s_unselected)
}, trial, prev_trial, Previous_Choice, stim1[prev_trial], stim2[prev_trial]), by = subject]

# 去除辅助列输出结果
result <- data[, .(subject, stim1, stim2, Chosen, outcome, Previous_Choice, Previous_Outcome, S_choice)]

效果验证

用你提供的前6行测试数据运行,输出结果和期望示例完全匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 07:06:03