【问题标题】:Conditional fill value in DataframeDataframe 中的条件填充值
【发布时间】:2018-05-06 13:02:47
【问题描述】:

我有一个如下所示的数据框:

Date        Avc1     Xrt2      Var3     Var4
2017-04-04  0        0         0        0
2017-04-04  10       18        22       25
2017-04-04  8        12        16       20
2017-04-04  5        10        13       18

现在我想有条件地填充 Var3 和 Var4 的值,只要它的值为 0。

输出:

Date        Avc1     Xrt2      Var3     Var4
2017-04-04  0        0         22       25
2017-04-04  10       18        22       25
2017-04-04  8        12        16       20
2017-04-04  5        10        13       18

【问题讨论】:

    标签: r dataframe dplyr


    【解决方案1】:

    使用:

    df[4:5] <- lapply(df[4:5], function(x) {i <- which(x == 0); x[i] <- x[i+1]; x})
    

    给予:

    > df
            Date Avc1 Xrt2 Var3 Var4
    1 2017-04-04    0    0   22   25
    2 2017-04-04   10   18   22   25
    3 2017-04-04    8   12   16   20
    4 2017-04-04    5   10   13   18
    

    na.locf 的另一种可能性来自zoo-package:

    i <- which(df == 0, arr.ind = TRUE)
    
    df[i[i[,2] %in% 4:5,]] <- NA
    
    df <- zoo::na.locf(df, fromLast = TRUE)
    

    【讨论】:

    • 谢谢它的工作,但我在这里需要一点帮助,如果正好低于单元格的值也是 0,我想在单元格下面循环它直到我得到非零值。
    • @VectorJX zoo-package 的第二种可能性可以解决这个问题:-)
    • 或者先把数据框的顺序倒过来
    【解决方案2】:

    这里有几个选项。在前 2 个中,我使用 mutate_at 从这些列中删除 0,然后使用 fill 从 tidyr 向上填充。

    在第三个中,如果该列中的值为 0,我使用lead 从下面获取值。

    library(tidyverse)
    
    df %>%
        mutate_at(vars(Var3, Var4), function(x) ifelse(x == 0, NA, x)) %>%
        fill(Var3, Var4, .direction = "up")
    #> # A tibble: 4 x 5
    #>   Date        Avc1  Xrt2  Var3  Var4
    #>   <date>     <int> <int> <int> <int>
    #> 1 2017-04-04     0     0    22    25
    #> 2 2017-04-04    10    18    22    25
    #> 3 2017-04-04     8    12    16    20
    #> 4 2017-04-04     5    10    13    18
    
    df %>%
        mutate_at(vars(Var3, Var4), na_if, 0) %>%
        fill(Var3, Var4, .direction = "up")
    #> # A tibble: 4 x 5
    #>   Date        Avc1  Xrt2  Var3  Var4
    #>   <date>     <int> <int> <int> <int>
    #> 1 2017-04-04     0     0    22    25
    #> 2 2017-04-04    10    18    22    25
    #> 3 2017-04-04     8    12    16    20
    #> 4 2017-04-04     5    10    13    18
    
    df %>%
        mutate_at(vars(Var3, Var4), function(x) ifelse(x == 0, lead(x), x))
    #> # A tibble: 4 x 5
    #>   Date        Avc1  Xrt2  Var3  Var4
    #>   <date>     <int> <int> <int> <int>
    #> 1 2017-04-04     0     0    22    25
    #> 2 2017-04-04    10    18    22    25
    #> 3 2017-04-04     8    12    16    20
    #> 4 2017-04-04     5    10    13    18
    

    由reprex package (v0.2.0) 于 2018 年 5 月 6 日创建。

    【讨论】:

    • 正是我的想法......(你在几秒钟前发布了):)。这是我的方法,df %&gt;% mutate_at(vars(starts_with('Var')), funs(replace(., . == 0, NA))) %&gt;% fill(everything(), .direction = 'up')
    • @camille 非常感谢。
    猜你喜欢
    • 2021-11-23
    • 1970-01-01
    • 2015-02-14
    • 2020-01-16
    • 2023-03-19
    • 2022-10-13
    • 2015-10-05
    • 2021-01-09
    • 1970-01-01
    相关资源
    最近更新 更多