【问题标题】:Overwrite a specific value in a dataframe, based on matching values根据匹配值覆盖数据框中的特定值
【发布时间】:2019-08-23 15:27:53
【问题描述】:

我的数据格式如下:

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

但如何将其放回原始数据框中?

Tidyverse 的答案对我来说更容易使用,但我愿意接受任何解决方案。

【问题讨论】:

标签: r dplyr tidyverse


【解决方案1】:

使用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

【讨论】:

    【解决方案2】:

    在这里,一种有效的方法是将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
    

    【讨论】:

      【解决方案3】:

      使用 1) 的一种可能的 tidyverse 方法。 anti_joindf 中删除将被替换的行和 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
      

      【讨论】:

        猜你喜欢
        • 2021-03-22
        • 2017-12-15
        • 1970-01-01
        • 1970-01-01
        • 2022-08-03
        • 2018-07-05
        • 2019-04-04
        • 2014-04-06
        • 1970-01-01
        相关资源
        最近更新 更多