如何使用tidyverse在宽格式R数据表中为满足双列条件的行批量赋值0(保留指定列)
Great question! Switching from Base R to tidyverse for this kind of conditional row update is totally feasible, and there are a couple of clean, idiomatic approaches to get your desired result. Let's break them down:
First, let's recap your setup
Sample input data:
df <- data.frame(id1 = c("a" , "b", "c"), id2 = c("a", "a", "d"), n1 = c(2,2,0), n2 = c(2,1,1), n3 = c(0,1,1), n4 = c(0,1,1))
Your goal: For rows where id1 == "b" and id2 == "a", set every column except n3 to 0, resulting in this output:
id1 id2 n1 n2 n3 n4 a a 2 2 0 0 b a 0 0 1 0 c d 0 1 1 1
(Note: I corrected the third row's id1 in your desired output to match the input data's "c" instead of "b" to keep consistency)
Tidyverse Solution 1: mutate() + across() + case_when()
This is the most concise and direct method, leveraging tidyverse's vectorized operations:
library(tidyverse) df_updated <- df %>% mutate( # Target all columns except n3 across(-n3, # Apply conditional logic: set to 0 if the row matches, else keep original value ~ case_when(id1 == "b" & id2 == "a" ~ 0, TRUE ~ .x)) ) print(df_updated)
Tidyverse Solution 2: rows_update() for explicit row updates
If you prefer a more explicit, row-focused approach (great for more complex update rules later), you can create a subset of rows to modify and merge them back into the original data:
library(tidyverse) # Create a dataframe with only the rows that need updating, setting non-n3 columns to 0 update_template <- df %>% filter(id1 == "b" & id2 == "a") %>% mutate(across(-n3, ~0)) # Update the original dataframe with the modified rows df_updated <- df %>% rows_update(update_template, by = c("id1", "id2")) print(df_updated)
How these work
- Solution 1 uses
across(-n3)to select every column exceptn3, then appliescase_when()to each of those columns. This keeps the logic contained in a single pipeline step. - Solution 2 isolates the rows that need changes, modifies them, then uses
rows_update()to overwrite only those rows in the original dataframe. This is helpful if you need to reuse the update logic elsewhere, or if your conditions become more complex.
Either approach will give you exactly the output you're looking for, while staying true to tidyverse's readable, pipeline-based style.
内容的提问来源于stack exchange,提问作者Anh

