4

Let's say I have a dataframe of scores

library(dplyr)

id <- c(1 , 2)
name <- c('John', 'Ninaa')
score1 <- c(8, 6)
score2 <- c(NA, 7)

df <- data.frame(id, name, score1, score2)

Some mistakes have been made so I want to correct them. My corrections are in a different dataframe.

id <- c(2,1)
column <- c('name', 'score2')
new_value <- c('Nina', 9)
corrections <- data.frame(id, column, new_value)

I want to search the dataframe for the correct id and column and change the value. I have tried something with match but I don't know how mutate the correct column.

df %>% mutate(corrections$column = replace(corrections$column, match(corrections$id, id), corrections$new_value))

2 Answers 2

3

We could join by 'id', then mutate across the columns specified in the column and replace the elements based on the matching the corresponding column name (cur_column()) with the column

library(dplyr)
df %>% 
  left_join(corrections) %>% 
  mutate(across(all_of(column), ~ replace(.x, match(cur_column(), 
     column), new_value[match(cur_column(), column)]))) %>% 
  select(names(df))

-output

  id name score1 score2
1  1 John      8      9
2  2 Nina      6      7
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much, I could never have thought of this. I checked and it works!
I just found out that this solution doesn't work if you have multiple corrections for one id. It works well for the question I asked though!
2

It's an implementation of a feasible idea with dplyr::rows_update, though it involves functions of multiple packages. In practice I prefer a moderately parsimonious approach.

library(tidyverse)

corrections %>%
  group_by(id) %>%
  group_map(
    ~ pivot_wider(.x, names_from = column, values_from = new_value) %>% type_convert,
    .keep = TRUE) %>%
  reduce(rows_update, by = 'id', .init = df)

#   id name score1 score2
# 1  1 John      8      9
# 2  2 Nina      6      7

1 Comment

Actually, if you have multiple corrections for one id, this is the solution that works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.