【问题标题】:How can I get row-wise max based on condition of specific column in R dataframe?如何根据 R 数据框中特定列的条件获得逐行最大值?
【发布时间】:2019-10-02 02:20:09
【问题描述】:

我正在尝试通过几列(气候缺水-def_59_z_#)获得最大值,具体取决于已经过去了多少时间(火灾后的时间-YEAR.DIFF)。以下是条件:

  • 如果已过 1 年,请选择第一年的赤字值。 (def_59_z_1)。
  • 如果 2 年:前 2 年的最大赤字。
  • 如果 3 年:前 3 年的最大赤字。
  • 如果 4 年:前 4 年的最大赤字。
  • 如果 5 或更多年:前 5 年最多。

但是,当我包含条件时,我无法提取逐行最大值。有几个现有的帖子解决了按行的最小值和最大值(例如12)和sd(例如3)——但这些不使用条件。我尝试过使用apply,但是当我涉及多个列以及条件要求时,我无法找到解决方案。

以下代码只是在新列def59_z_max15 中返回 3.5,这是数据帧中出现的最大值 -- exceptYEAR.DIFF 为 1 时,在这种情况下 def_50_z_1是直接返回的。但对于所有其他条件,我想要 0.98、0.67、0.7、1.55、1.28 - 反映指定列的行最大值的值。链接到样本数据here。我怎样才能做到这一点?

感谢任何/所有建议!

data <- data %>%
mutate(def59_z_max15 = ifelse(YEAR.DIFF == 1,
                            (def59_z_1),
                            ifelse(YEAR.DIFF == 2,
                                   max(def59_z_1, def59_z_2),
                                   ifelse(YEAR.DIFF == 3,
                                          max(def59_z_1, def59_z_2, def59_z_3),
                                          ifelse(YEAR.DIFF == 4,
                                                 max(def59_z_1, def59_z_2, def59_z_3, def59_z_4),
                                                 max(def59_z_1, def59_z_2, def59_z_3, def59_z_4, def59_z_5))))))

【问题讨论】:

    标签: r if-statement max dplyr rowwise


    【解决方案1】:

    将此函数放入apply 家族函数中

    func <- function(x) {
    first.val <- x[1]
    if (first.val < 5) {
    return(max(x[2:(first.val+)])
    } else {
    return(max(x[2:6]))
    }
    }
    

    您想要的输出应通过以下方式获得:

    apply(data, 1, function(x) func(x)) #do it by row by setting arg2 = 1
    

    【讨论】:

    • 谢谢你,@Dij。但我无法弄清楚为什么我不使用 max(x[2:(1+first.val)]。为什么使用索引 1 会拉出正确的列(第二个)但使用索引 2 却没有t?
    【解决方案2】:

    一个选项是在循环中分别为每组条件获取pmax(按行max - 矢量化)(map - 如果'YEAR.DIFF'的值为1,则仅选择'def_59_z_1',对于 2,获取 'def_59_z_1' 和 'def_59_z_2' 的最大值,...,对于 5,'def_59_z_1' 到 'def_59_z_5' 的最大值,coalesce 列在一起并替换 @987654325 的其余部分@ 与所有“def59_z”列中的pmax

    library(tidyverse)
    out <- map_dfc(1:5, ~
             df1 %>% 
               select(seq_len(.x) + 1) %>% 
               transmute(val = na_if((df1[["YEAR.DIFF"]] == .x)*
                   pmax(!!! rlang::syms(names(.))), 0))) %>%  
      transmute(def59_z_max15 = coalesce(!!! rlang::syms(names(.)))) %>%
      bind_cols(df1, .)%>%
      mutate(def59_z_max15 = case_when(is.na(def59_z_max15) ~ 
             pmax(!!! rlang::syms(names(.)[2:6])), TRUE ~ def59_z_max15))
    head(out, 10)
    #   YEAR.DIFF def59_z_1 def59_z_2 def59_z_3 def59_z_4 def59_z_5 def59_z_max15
    #1          5      0.25     -2.11      0.98     -0.07      0.31          0.98
    #2          9      0.67      0.65     -0.27      0.52      0.26          0.67
    #3         10      0.56      0.33      0.03      0.70     -0.09          0.70
    #4          2     -0.34      1.55     -1.11     -0.40      0.94          1.55
    #5          4      0.98      0.71      0.41      1.28     -0.14          1.28
    #6          3      0.71     -0.17      1.70     -0.57      0.43          1.70
    #7          4     -1.39     -1.71     -0.89      0.78      1.22          0.78
    #8          4     -1.14     -1.46     -0.72      0.74      1.32          0.74
    #9          2      0.71      1.39      1.07      0.65      0.29          1.39
    #10         1      0.28      0.82     -0.64      0.45      0.64          0.28
    

    数据

    df1 <- read.csv("https://raw.githubusercontent.com/CaitLittlef/random/master/data.csv")
    

    【讨论】:

    • @Dij 用于评估列以获取值
    猜你喜欢
    • 2018-04-12
    • 1970-01-01
    • 2020-04-06
    • 1970-01-01
    • 2020-02-24
    • 1970-01-01
    • 1970-01-01
    • 2016-08-06
    • 2022-08-11
    相关资源
    最近更新 更多