I made a better reprex based on your suggestions. In case of repeated lines, the approaches based on rows_update and match seem to fail, whereas those based on join are robust. Since I will need this a lot, I wrote an ugly function. If anyone can to this better, please be my guest. Otherwise I will accept the answer by Duck.
Please consider the following tibbles df and df2
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
join_replace <- function(val_ini, x, val_new, x2 ){
require(magrittr)
df1 <- tibble(value=val_ini, x_pos=x)
df2 <- tibble(value_new=val_new, x_pos=x2)
df_out <- df1 %>%
left_join(y=df2) %>%
mutate(value_new=if_else(is.na(value_new), value, value_new)) %$%
value_new %>% as.vector
}
df <- tibble(x=seq(10), y=letters[seq(10)])
df <- bind_rows(df,df)
df
#> # A tibble: 20 x 2
#> x y
#> <int> <chr>
#> 1 1 a
#> 2 2 b
#> 3 3 c
#> 4 4 d
#> 5 5 e
#> 6 6 f
#> 7 7 g
#> 8 8 h
#> 9 9 i
#> 10 10 j
#> 11 1 a
#> 12 2 b
#> 13 3 c
#> 14 4 d
#> 15 5 e
#> 16 6 f
#> 17 7 g
#> 18 8 h
#> 19 9 i
#> 20 10 j
df2 <- tibble(x=c(2,3,5), y=c("kk", "xx", "zz"))
df2
#> # A tibble: 3 x 2
#> x y
#> <dbl> <chr>
#> 1 2 kk
#> 2 3 xx
#> 3 5 zz
df_out <- df %>% left_join(df2 %>% rename(y1=y)) %>%
mutate(y=ifelse(!is.na(y1),y1,y)) %>% select(-y1)
#> Joining, by = "x"
df_out
#> # A tibble: 20 x 2
#> x y
#> <dbl> <chr>
#> 1 1 a
#> 2 2 kk
#> 3 3 xx
#> 4 4 d
#> 5 5 zz
#> 6 6 f
#> 7 7 g
#> 8 8 h
#> 9 9 i
#> 10 10 j
#> 11 1 a
#> 12 2 kk
#> 13 3 xx
#> 14 4 d
#> 15 5 zz
#> 16 6 f
#> 17 7 g
#> 18 8 h
#> 19 9 i
#> 20 10 j
df_out2 <- df %>%
mutate(y=join_replace(y, x, df2$y, df2$x))
#> Loading required package: magrittr
#> Joining, by = "x_pos"
df_out2
#> # A tibble: 20 x 2
#> x y
#> <int> <chr>
#> 1 1 a
#> 2 2 kk
#> 3 3 xx
#> 4 4 d
#> 5 5 zz
#> 6 6 f
#> 7 7 g
#> 8 8 h
#> 9 9 i
#> 10 10 j
#> 11 1 a
#> 12 2 kk
#> 13 3 xx
#> 14 4 d
#> 15 5 zz
#> 16 6 f
#> 17 7 g
#> 18 8 h
#> 19 9 i
#> 20 10 j
Created on 2020-10-06 by the reprex package (v0.3.0.9001)
I am trying to achieve something simple: for every x element in df also present in df2, change the value of y in df to the corresponding y value in df2.
I can achieve this with map or other rather cumbersome strategies, but perhaps someone can suggest something simpler?
Thanks!
You can try an approach with left_join()
and a conditional:
library(dplyr)
#Code
df <- df %>% left_join(df2 %>% rename(y1=y)) %>%
mutate(y=ifelse(!is.na(y1),y1,y)) %>% select(-y1)
Output:
# A tibble: 10 x 2
x y
<dbl> <chr>
1 1 a
2 2 kk
3 3 xx
4 4 d
5 5 zz
6 6 f
7 7 g
8 8 h
9 9 i
10 10 j
对于dplyr
方式,您可以执行以下操作:
df %>% rows_update(df2, by = "x")
What about joining it?
df<-df %>%
left_join(df2,by="x") %>%
drop_na() %>%
dplyr::select(x,y.y) %>%
rename("y"="y.y")
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.