0

Say I have df1 and df2. I want to replace all elements from df2$X2 that correspond to df1$X1 into df1$X2. My attempt does the replacements, but not in the way I would like. I am ultimtely trying to get df1 to look like df3. Any suggestions?

df1 <- data.frame(cbind(c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5), NA))
df2 <- data.frame(cbind(c(1, 4, 5), c("A", "B", "C")))
df1$X2 <- replace(df1$X2, df1$X1 %in% df2$X1, df2$X2)
df3 <- structure(list(X1 = c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 
4, 4, 4, 5, 5, 5, 5), X2 = c("A", "A", "A", "A", NA, NA, NA, 
NA, NA, NA, NA, NA, "B", "B", "B", "B", "C", "C", "C", "C")), row.names = c(NA, 
-20L), class = "data.frame")
user13589693
  • 369
  • 1
  • 8
  • cbind creates a matrix, therefore, the first column in df2 i.e (1,4,5) will be a string instead of doubles/integers: > df2 <- data.frame(cbind(c(1, 4, 5), c("A", "B", "C"))) > str(df2) 'data.frame': 3 obs. of 2 variables: $ X1: chr "1" "4" "5" $ X2: chr "A" "B" "C" > – Karthik S Oct 21 '20 at 14:58

2 Answers2

0

You can use match :

df1$X2 <- df2$X2[match(df1$X1, df2$X1)]
identical(df1, df3)
#[1] TRUE
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
0

You can use dplyr:

> df1 %>% select(-X2) %>% left_join(df2)
Joining, by = "X1"
   X1   X2
1   1    A
2   1    A
3   1    A
4   1    A
5   2 <NA>
6   2 <NA>
7   2 <NA>
8   2 <NA>
9   3 <NA>
10  3 <NA>
11  3 <NA>
12  3 <NA>
13  4    B
14  4    B
15  4    B
16  4    B
17  5    C
18  5    C
19  5    C
20  5    C
> 
Karthik S
  • 11,348
  • 2
  • 11
  • 25