具有tidyverse dplyr的通用数据帧更新功能,如sql-update

时间:2017-11-16 14:48:11

标签: r if-statement dplyr tidyverse mutate

我搜索一般的数据帧更新函数,如sql-update,它更新第一个数据帧中的值,以防键与第二个数据帧中的键匹配。是否有更通用的方式,如我的例子,也许还通过考虑值名称?像通用的dplyr :: update(df1,df2,by =“key”)函数?

library(tidyverse)
# example data frame
df1 <- as_data_frame(list(key = c(1,2,3,4,5,6,7,8,9),
                          v1 = c(11,12,13,14,15,16,17,18,19),
                          v2 = c(21,22,23,24,25,26,27,28,29),
                          v3 = c(31,32,33,34,35,36,37,38,39),
                          v4 = c(41,42,43,44,45,46,47,48,49)))
df2 <- as_data_frame(list(key = c(3,5,9),
                          v2 = c(231,252,293),
                          v4 = c(424,455,496)))

# update df1 with values from df2 where key match
org_names <- df1 %>% names()
df1 <- df1 %>% 
  left_join(df2, by = "key") %>% 
  mutate(v2 = ifelse(is.na(v2.y), v2.x, v2.y),
         v4 = ifelse(is.na(v4.y), v4.x, v4.y)) %>% 
  select(org_names)

> df1
# A tibble: 9 x 5
key    v1    v2    v3    v4
<dbl> <dbl> <dbl> <dbl> <dbl>
1     1    11    21    31    41
2     2    12    22    32    42
3     3    13   231    33   424
4     4    14    24    34    44
5     5    15   252    35   455
6     6    16    26    36    46
7     7    17    27    37    47
8     8    18    28    38    48
9     9    19   293    39   496
> 

1 个答案:

答案 0 :(得分:1)

1)%&lt;&gt;% Magrittr具有复合分配管道:

library(magrittr)

df1 %>% 
    { keys <- intersect(.$key, df2$key)
    .[match(keys, .$key), names(df2)] %<>% { df2[match(keys, df2$key), ] }
    .
}

对于正在考虑的问题,简化为此,因为df2中的所有密钥都在df1中:

df1 %>% { .[match(df2$key, .$key), names(df2)]  %<>% { df2 }; . }

2)&lt; - 基本的R赋值运算符也可以以相同的方式使用,事实上,代码比(1)短:

df1 %>% 
    { keys <- intersect(.$key, df2$key)
    .[match(keys, .$key), names(df2)] <- df2[match(keys, df2$key), ]
    .
}

但是,对于所考虑的问题,df2中的所有键都在df1中,因此它简化为:

df1 %>% { .[match(df2$key, .$key), names(df2)] <- df2; . }

3)mutate_cond 使用this SO post中定义的mutate_cond,我们可以编写以下内容。

df1 %>% mutate_cond(.$key %in% df2$key, v2 = df2$v2, v4 = df2$v4)

注意:如果df1df2中的密钥都是唯一的,则前两种方法有效。第三个还要求密钥的顺序相同,df2中的每个密钥都在df1中。问题中的问题满足了这些。

更新:稍微概括了(1)和(2)中的代码。

相关问题