r语言 - 根据匹配的值覆盖数据帧中的特定值



我的数据格式如下:

#>   country year value
#> 1     AUS 2019   100
#> 2     USA 2019   120
#> 3     AUS 2018    90
df <- data.frame(stringsAsFactors=FALSE,
country = c("AUS", "USA", "AUS"),
year = c(2019, 2019, 2018),
value = c(100, 120, 90)
)

我有一个单行数据帧,它表示应覆盖数据中现有记录的修订。

#>   country year value
#> 1     AUS 2019   500
df2 <- data.frame(stringsAsFactors=FALSE,
country = c("AUS"),
year = c(2018),
value = c(500)
)

我想要的输出是:

#>   country year value
#> 1     AUS 2019   100
#> 2     USA 2019   120
#> 3     AUS 2018   500

我知道如何找到要覆盖的行:

library(tidyverse)
df %>% filter(country == overwrite$country & year == overwrite$year) %>% 
mutate(value = overwrite$value)

但是如何将其放回原始数据帧中呢?

整洁的答案对我来说更容易使用,但我对任何解决方案都持开放态度。

使用mutateif_else

library(tidyverse)
df %>% 
mutate(value = if_else(country %in% df2$country & year %in% df2$year, df2$value, value))

结果:

country year value
1     AUS 2019   100
2     USA 2019   120
3     AUS 2018   500

在这里,一种有效的方法是将ondata.table连接起来。 将"data.frame"转换为"data.table"(setDT(df)(,将on与"国家"上的"df2"连接,"年份"分配(:=(第二个数据集(i.value(中的"值"列以替换原始数据集中的"值">

library(data.table)
setDT(df)[df2, value := i.value, on = .(country, year)]
df
#    country year value
#1:     AUS 2019   100
#2:     USA 2019   120
#3:     AUS 2018   500

一种可能的整理方法,使用1(。anti_join从将要替换的行中删除df和 2(。bind_rows添加df2中的替换行:

library(dplyr)
anti_join(df, df2, by = c("country", "year")) %>% bind_rows(df2)
#>   country year value
#> 1     AUS 2019   100
#> 2     USA 2019   120
#> 3     AUS 2018   500

或者,另一个使用 1(。right_join连接新旧值和 2(。coalesce仅保留新值:

right_join(df2, df, by = c("country", "year")) %>%
transmute(country, year, value = coalesce(value.x, value.y))
#>   country year value
#> 1     AUS 2019   100
#> 2     USA 2019   120
#> 3     AUS 2018   500

最新更新