R中data.table查找值的上一次出现并获取对立列值如何实现
实现方案
首先构造你提供的示例数据(修正原structure中行数不匹配的问题):
library(data.table) dt <- data.table( stim1 = c(2L, 1L, 2L, 1L, 3L), stim2 = c(3L, 3L, 1L, 2L, 1L) )
实现思路
由于每一行的计算依赖之前所有行的结果,我们维护一个全局的缓存向量,记录每个刺激值最后一次出现时对应的另一列值,遍历每一行时先查询缓存赋值Prev1、Prev2,再更新缓存,时间复杂度为O(n),是最高效的实现方式。
实现代码
# 初始化缓存,键是刺激值,值是对应另一列的最新值 cache <- c() # 逐行处理 for (i in 1:nrow(dt)) { s1 <- dt$stim1[i] s2 <- dt$stim2[i] # 赋值Prev1和Prev2,不存在则返回NA dt$Prev1[i] <- ifelse(as.character(s1) %in% names(cache), cache[as.character(s1)], NA) dt$Prev2[i] <- ifelse(as.character(s2) %in% names(cache), cache[as.character(s2)], NA) # 更新缓存:当前行s1对应的另一列是s2,s2对应的另一列是s1 cache[as.character(s1)] <- s2 cache[as.character(s2)] <- s1 }
输出结果
运行后dt的结果完全符合预期:
stim1 stim2 Prev1 Prev2 1: 2 3 NA NA 2: 1 3 NA 2 3: 2 1 3 3 4: 1 2 2 1 5: 3 1 1 2
如果需要处理百万级以上的大表,可以把循环逻辑改成Rcpp实现,速度会进一步提升,普通规模的数据上述方案已经足够高效。
内容的提问来源于stack exchange,提问作者user15791858
相关产品推荐
相关产品推荐

