1

I want to add extra columns depending on values of code which are defined in VAR

DF <- data.frame(id = c(1:5), code = c("A","B","C","D","E"), sub = c("A1","B1","C1","D1","E1"))

   id code sub
1  1    A  A1
2  2    B  B1
3  3    C  C1
4  4    D  D1
5  5    E  E1

VAR <- c("A","B")

How result should be:

  id code sub   AB ABsub
1  1    A  A1    A    A1
2  2    B  B1    B    B1
3  3    C  C1 <NA>  <NA>
4  4    D  D1 <NA>  <NA>
5  5    E  E1 <NA>  <NA>
Darren Tsai
  • 32,117
  • 5
  • 21
  • 51
hklovs
  • 611
  • 1
  • 4
  • 16

4 Answers4

2

Or using dplyr:

library(dplyr)

DF<-data.frame(id=c(1:5),code=c("A","B","C","D","E"),sub=c("A1","B1","C1","D1","E1"), stringsAsFactors = FALSE)

VAR<-c("A","B")

DF <- DF %>%
  mutate(AB = ifelse(code %in% {{VAR}}, code, NA_character_)) %>%
  mutate(ABsub = ifelse(code == AB, sub, NA_character_))

with:

> DF
  id code sub   AB ABsub
1  1    A  A1    A    A1
2  2    B  B1    B    B1
3  3    C  C1 <NA>  <NA>
4  4    D  D1 <NA>  <NA>
5  5    E  E1 <NA>  <NA>

Also works if VAR would equal c("A", "B", "C") but we do not know if that is what you are after.

Paul van Oppen
  • 1,443
  • 1
  • 9
  • 18
2

A dplyr solution with across():

library(dplyr)

DF %>%
  mutate(across(-id, ~ replace(.x, !(code %in% VAR), NA), .names = "AB{col}"))

#   id code sub ABcode ABsub
# 1  1    A  A1      A    A1
# 2  2    B  B1      B    B1
# 3  3    C  C1   <NA>  <NA>
# 4  4    D  D1   <NA>  <NA>
# 5  5    E  E1   <NA>  <NA>

or with left_join():

DF %>%
  filter(code %in% VAR) %>% 
  left_join(DF, ., by = "id", suffix = c("", "AB"))

#   id code sub codeAB subAB
# 1  1    A  A1      A    A1
# 2  2    B  B1      B    B1
# 3  3    C  C1   <NA>  <NA>
# 4  4    D  D1   <NA>  <NA>
# 5  5    E  E1   <NA>  <NA>

Note: If you have multiple columns in your real data, you don't need to type

mutate(Col1 = ifelse(...), Col2 = ifelse(...), etc.)

one by one.

Darren Tsai
  • 32,117
  • 5
  • 21
  • 51
2

A simple base R option using merge + subset

merge(DF,subset(DF,code %in% VAR),by = "id",all = TRUE)

such that

> merge(DF,subset(DF,code %in% VAR),by = "id",all = TRUE)
  id code.x sub.x code.y sub.y
1  1      A    A1      A    A1
2  2      B    B1      B    B1
3  3      C    C1   <NA>  <NA>
4  4      D    D1   <NA>  <NA>
5  5      E    E1   <NA>  <NA>
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81
1

Here's a solution

ABsub <- ifelse(DF$code %in% VAR, DF$code, NA)
cbind(DF, ABsub)
Doctor G
  • 163
  • 9