R语言查找两列大小关系反转的首个后续行号方法
R查找两列数值首次大小反转的行号
前置已有代码与数据
- 测试数据框
dx定义:
dx <- structure(list(a = c(0.916290731874155, 2.89037175789616, 2.14658084451746, -2.62103882411258, -2.07944154167984, 2.00533356952611, -1.24319351747922, 0.42744401482694, 1.29532258291416, -2.03292152604494, -0.606135803570316, -0.693147180559945), b = c(0.550046336919272, 0.228258651980981, -0.577634293438101, 0.135801541159061, 0.644357016390513, -2.30258509299405, -0.0870113769896297, 1.71297859137494, 0.17958557697508, -1.65140211153313, 1.31218638896617, 2.19935904986485), c = c(0.0988458346366325, -3.34403896782221, 1.99243016469021, 0.737598943130779, 0.178691788743376, 2.20727491318972, -1.40242374304977, -1.256836293883, -2.16905370036952, 2.91777073208428, 0.138586163286146, -0.946143695023836), d = c(2.57963390914446, -5.14458326660599, 1.83258146374831, 1.15057202759882, 0.0613689463762919, -2.23359222150709, 4.34236137828145, -3.44854350225935, 1.29098418131557, -0.356674943938732, -0.21868920096483, -0.810930216216329), e = c(1.65140211153313, 0.220400065368459, -0.044951387862266, 0.0773866636154201, -1.49877234454658, 1.36219680954083, 2.07179039494432, -3.07731226054641, -0.916290731874155, 1.65822807660353, 0.451985123743057, -0.810930216216329)), class = "data.frame", row.names = 2:13)
- 前置计算逻辑(生成
sd/sqmat/G/open/s/b):
# 计算每列均值 sd <- (colSums(dx)/12) # 计算所有值绝对值的平方根 sqmat <- sqrt(abs(dx)) # 生成判断矩阵G G <- ifelse((sqmat/3) > (sd*4), 1, 0) # 查找每列首次出现1的行索引 open <- t(as.matrix(max.col(t(G) == 1, "first"))) # 比较第1、3列首次触发位置的取值,分配s和b if (dx[open[,1],1] > dx[open[,3],3]) { s <- dx[open[,1],1] b <- dx[open[,3],3] } else{ s <- dx[open[,3],3] b <- dx[open[,1],1] }
- 需求:找到比较所用行的后续行中,两列大小关系首次反转的行号(本例预期结果为第4行),反转规则为初始取值更大的列在该行取值更小。
实现代码
直接在上述代码后追加以下逻辑即可:
# 提取两列首次出1的行索引 col1_first_pos <- open[, 1] col3_first_pos <- open[, 3] # 确定查找起始行:取两个首次出现位置的最大值的下一行,保证是比较完成后的后续行 start_search_row <- max(col1_first_pos, col3_first_pos) + 1 # 记录初始大小关系 is_col1_larger <- dx[col1_first_pos, 1] > dx[col3_first_pos, 3] # 按初始关系匹配反转条件,查找第一个满足条件的行 if (is_col1_larger) { # 初始第1列更大,找首个第1列值小于第3列值的行 match_seq <- which(dx[start_search_row:nrow(dx), 1] < dx[start_search_row:nrow(dx), 3]) } else { # 初始第3列更大,找首个第3列值小于第1列值的行 match_seq <- which(dx[start_search_row:nrow(dx), 3] < dx[start_search_row:nrow(dx), 1]) } # 换算为dx整体的行索引,再取对应行名即为实际行号 reverse_row_index <- match_seq[1] + start_search_row - 1 reverse_row <- as.integer(row.names(dx)[reverse_row_index])
结果验证
运行上述代码后reverse_row返回值为4,和预期结果完全一致。
内容的提问来源于stack exchange,提问作者bcsfh
相关产品推荐
相关产品推荐

