简体   繁体   English

Dplyr 替换元素列表

[英]Dplyr replace list of elements

I made a better reprex based on your suggestions.我根据你的建议做了一个更好的 reprex。 In case of repeated lines, the approaches based on rows_update and match seem to fail, whereas those based on join are robust.在重复行的情况下,基于rows_update 和match 的方法似乎失败了,而基于join 的方法是健壮的。 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请考虑以下小标题 df 和 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)reprex 包(v0.3.0.9001) 于 2020 年 10 月 6 日创建

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.我试图实现一些简单的事情:对于 df2 中也存在的 df 中的每个 x 元素,将 df 中 y 的值更改为 df2 中相应的 y 值。

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:您可以尝试使用left_join()和条件的方法:

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")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM