【问题标题】:Match date and category then replace value in r匹配日期和类别,然后替换 r 中的值
【发布时间】:2019-08-24 11:45:05
【问题描述】:

我有场景 A 和 B,我在某个日期范围内记录了值。我想将场景 B 中的所有零 (0) 值替换为日期相同的场景 A 中的值。

例子

On.Date     Scenario   Value
2019-01-01      A       1
2019-01-02      A       2
2019-01-03      A       3
2019-01-04      A       4
2019-01-05      A       5
2019-01-01      B       1
2019-01-02      B       0
2019-01-03      B       1
2019-01-04      B       0
2019-01-05      B       1

我正在寻找的解决方案

On.Date     Scenario   Value
2019-01-01      A       1
2019-01-02      A       2
2019-01-03      A       3
2019-01-04      A       4
2019-01-05      A       5
2019-01-01      B       1
2019-01-02      B       2
2019-01-03      B       1
2019-01-04      B       4
2019-01-05      B       1

我已经尝试过 if_else 语句、mutate_if、matches、gathers 以及我发现的许多其他语句,但我似乎无法让它发挥作用。

任何帮助将不胜感激!

dt <- rbind(data.frame(On.Date = seq.Date(as.Date('2019-01-01'), 
                                          as.Date('2019-01-05'), by = 1), 
                       Scenario = "A",
                       value = rep_len(1:5, 5)), 
            data.frame(On.Date = seq.Date(as.Date('2019-01-01'), 
                                               as.Date('2019-01-05'), by = 1), 
                            Scenario = "B",
                            value = rep_len(1:0, 5)))

【问题讨论】:

    标签: r date replace dplyr match


    【解决方案1】:

    我们可以先找出Scenario == "B"value = 0 所在的索引。然后我们match那些On.DateScenario == "A"的日期得到各自的value

    inds <- which(dt$Scenario == "B" & dt$value == 0)
    dt$value[inds] <- dt$value[match(dt$On.Date[inds], dt$On.Date[dt$Scenario == "A"])]
    
    dt
    #      On.Date Scenario value
    #1  2019-01-01        A     1
    #2  2019-01-02        A     2
    #3  2019-01-03        A     3
    #4  2019-01-04        A     4
    #5  2019-01-05        A     5
    #6  2019-01-01        B     1
    #7  2019-01-02        B     2
    #8  2019-01-03        B     1
    #9  2019-01-04        B     4
    #10 2019-01-05        B     1
    

    【讨论】:

    • Ronak,非常好的基础 R 方法。感谢您的帮助,并将其包含在我的代码中!
    【解决方案2】:

    base R 中带有ave 的选项

    dt$value <-  with(dt, ave(value, On.Date, FUN = function(x) replace(x, !x, x[1])))
    dt$value
    #[1] 1 2 3 4 5 1 2 1 4 1
    

    【讨论】:

      【解决方案3】:

      考虑到您的数据具有示例中的结构,dplyr 的一种可能性可能是:

      dt %>%
       group_by(On.Date) %>%
       mutate(value = if_else(value == 0, first(value), value))
      
         On.Date    Scenario value
         <date>     <fct>    <int>
       1 2019-01-01 A            1
       2 2019-01-02 A            2
       3 2019-01-03 A            3
       4 2019-01-04 A            4
       5 2019-01-05 A            5
       6 2019-01-01 B            1
       7 2019-01-02 B            2
       8 2019-01-03 B            1
       9 2019-01-04 B            4
      10 2019-01-05 B            1
      

      【讨论】:

      • tmfmnk,谢谢你的回答。我想我在没有考虑首先使用该功能的情况下围绕该解决方案跳舞。这是工作!
      猜你喜欢
      • 2018-02-26
      • 2017-01-06
      • 2021-07-04
      • 1970-01-01
      • 2013-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多