【问题标题】:Dplyr replace list of elementsDplyr替换元素列表
【发布时间】:2020-10-05 14:05:41
【问题描述】:

根据您的建议,我做了一个更好的代表。在重复行的情况下,基于 rows_update 和 match 的方法似乎失败了,而基于 join 的方法很健壮。因为我需要这个很多,所以我写了一个丑陋的函数。如果有人可以更好地做到这一点,请成为我的客人。否则我会接受鸭子的回答。

请考虑以下小标题 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

reprex package (v0.3.0.9001) 于 2020 年 10 月 6 日创建

我正在尝试实现一些简单的事情:对于 df 中也存在于 df2 中的每个 x 元素,将 df 中的 y 值更改为 df2 中相应的 y 值。

我可以通过地图或其他相当繁琐的策略来实现这一点,但也许有人可以提出更简单的建议?

谢谢!

【问题讨论】:

  • df$y[match(df2$x, df$x)] &lt;- df2$y 做你想做的事吗?
  • @AllanCameron 您共享的那段非常聪明的代码产生了与dplyr 相同的输出。太棒了!

标签: r dplyr tidyverse


【解决方案1】:

您可以尝试使用left_join() 和条件的方法:

library(dplyr)
#Code
df <- df %>% left_join(df2 %>% rename(y1=y)) %>%
  mutate(y=ifelse(!is.na(y1),y1,y)) %>% select(-y1)

输出:

# 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    

【讨论】:

    【解决方案2】:

    对于dplyr的方式,你可以这样做:

    df %>% rows_update(df2, by = "x")
    

    【讨论】:

      【解决方案3】:

      加入呢?

      df<-df %>% 
        left_join(df2,by="x") %>% 
        drop_na() %>% 
        dplyr::select(x,y.y) %>% 
        rename("y"="y.y")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多