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

如何用dplyr将check列中大于任意before列的值替换为NA?

Solution: Replace Check Columns with NA When Greater Than Any Before Column

Problem Recap

You need to replace values in check.1 to check.3 with NA if they exceed any value in before.1 to before.3 in the same row. Your initial attempt with mutate(across(check.1:check.3,~na_if(.x >before.1:before.3))) fails because the comparison isn't handled row-wise.

Sample Data

Let’s use explicit initial and target datasets for clarity:

library(dplyr)

# Initial input data
df <- tibble(
  before.1 = c(5, 3, 7),
  before.2 = c(4, 6, 2),
  before.3 = c(6, 2, 5),
  check.1 = c(7, 4, 6),
  check.2 = c(3, 7, 8),
  check.3 = c(5, 1, 9)
)

# Expected target result
target_df <- tibble(
  before.1 = c(5, 3, 7),
  before.2 = c(4, 6, 2),
  before.3 = c(6, 2, 5),
  check.1 = c(NA, NA, 6),
  check.2 = c(3, NA, NA),
  check.3 = c(5, 1, NA)
)

Correct Implementation

A simple, efficient approach leverages row-wise maximum values of the before columns: if a check value is greater than any before value, it will be greater than the row's maximum before value. Here’s how to implement this with dplyr:

result_df <- df %>%
  # Calculate row-wise maximum of before columns (ignore NAs if present)
  rowwise() %>%
  mutate(max_before = max(c_across(before.1:before.3), na.rm = TRUE)) %>%
  ungroup() %>%
  # Replace check values exceeding max_before with NA
  mutate(across(check.1:check.3, ~if_else(.x > max_before, NA_real_, .x))) %>%
  # Remove temporary max_before column
  select(-max_before)

# Confirm matches target
all.equal(result_df, target_df)
#> [1] TRUE

Why Your Initial Code Failed

before.1:before.3 creates a sequence of column names, but when used in na_if(.x > before.1:before.3), it attempts to compare the entire check column vector to all three before columns at once—not a row-by-row comparison. The rowwise() + c_across() combination fixes this by processing each row individually.

Alternative for Large Datasets

For big datasets, rowwise() can be slow. Use apply to compute row-wise max instead:

result_df <- df %>%
  mutate(max_before = apply(select(., before.1:before.3), 1, max, na.rm = TRUE)) %>%
  mutate(across(check.1:check.3, ~if_else(.x > max_before, NA_real_, .x))) %>%
  select(-max_before)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 03:35:18