如何在R数据框中为未及时响应的试次插入空白行?
问题描述
行为任务数据里,ecode(事件代码)列中30、31代表响应,小于30的是刺激。部分目标刺激(ecode为20、21、22)之后没有对应的响应代码(被试未及时响应),需要在这些目标刺激的行后面插入空白行,明确标记该试次无响应。
我尝试了两段代码,但都只在第一个指定位置插入空白行后就停止,没法完成所有目标行的插入操作。
尝试的代码
第一段代码
library(dplyr) myevents = read.csv(data) myevents2=myevents[myevents$ecode>=20 & myevents$ecode<30 & lead(myevents$ecode<20),] myrows = as.numeric(row.names(myevents2)) for(i in 1:length(myrows)){ myevents3 <- add_row(df, .after = i) }
第二段代码
myevents2=myevents[myevents$ecode>=20 & myevents$ecode<30 & lead(myevents$ecode<20),] myrows=as.numeric(myevents2$item) myevents3=data.frame() for(i in 1:length(myevents$item)){ if(myevents$item[i] %in% myrows){ myevents3 <- add_row(myevents, .after=i) } }
解决方法
之前的问题核心是:循环插入行时,每次插入都会改变原数据的行索引,但你仍用初始的索引值去定位插入位置,导致后续插入位置全部错位。以下两种方法可以解决:
方法一:反向循环插入
从最后一个需要插入的位置往前插,这样前面的插入操作不会影响后面的索引定位:
library(dplyr) # 读取数据(替换成你的实际文件路径) myevents <- read.csv("your_data_file.csv") # 筛选出需要在其后插入空白行的目标行索引 target_rows <- which(myevents$ecode %in% c(20,21,22) & lead(myevents$ecode, default = 0) < 20) # 反向循环插入空白行 myevents3 <- myevents for(i in rev(target_rows)){ myevents3 <- add_row(myevents3, .after = i) }
方法二:用dplyr逐行构建新数据
不直接修改原数据,而是逐行处理,遇到目标行就额外添加一行空行:
library(dplyr) library(purrr) myevents <- read.csv("your_data_file.csv") # 先标记出需要添加空白行的目标行 myevents <- myevents %>% mutate(need_blank = ecode %in% c(20,21,22) & lead(ecode, default = 0) < 20) # 逐行处理并构建新数据框 myevents3 <- myevents %>% rowwise() %>% group_split() %>% map_df(function(row){ if(row$need_blank){ bind_rows(row, tibble(.rows = 1)) } else { row } }) %>% select(-need_blank) # 移除标记列
这两种方法都能正确在所有符合条件的目标刺激行后插入空白行,解决你之前只插入第一行的问题。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

