如何根据 R 数据框中特定列的条件获取行最大值?
How can I get row-wise max based on condition of specific column in R dataframe?
我正在尝试根据经过的时间(火灾后的时间 - YEAR.DIFF
)跨多个列(气候缺水 -- def_59_z_#
)按行获得最大值.条件如下:
- 如果 1 年过去了,select 第一年的赤字值。
(
def_59_z_1
).
- 如果 2 年:前 2 年的最大赤字。
- 如果是 3 年:前 3 年的最大赤字。
- 如果是 4 年:前 4 年的最大赤字。
- 如果 5 或更多 年:前 5 年的最大值。
但是,当我包含一个条件时,我无法提取行式最大值。有几个现有的帖子可以解决按行的最小值和最大值(示例 and 2) and sd (example 3)——但这些不使用条件。我试过使用 apply
但当我涉及多个列以及条件要求时,我无法找到解决方案。
下面的代码只是 returns 新列 def59_z_max15
中的 3.5,这是数据帧中出现的最大值 -- except 当 YEAR.DIFF
为1,此时直接返回def_50_z_1
。但对于所有其他条件,我想要 0.98、0.67、0.7、1.55、1.28 —— 反映指定列的行最大值的值。 Link 采样数据 here。我怎样才能做到这一点?
我感谢 any/all 的建议!
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))))))
将此函数放入 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
一个选项是在循环中分别为每组条件获取 pmax
(按行 max
- 矢量化)(map
- 如果 'YEAR.DIFF' 是 1,select 只有 'def_59_z_1',对于 2,获取 'def_59_z_1' 和 'def_59_z_2' 的最大值,...,对于 5,最大值 'def_59_z_1' ] 到 'def_59_z_5'、coalesce
列,并将 NA
的其余部分替换为所有“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")
我正在尝试根据经过的时间(火灾后的时间 - YEAR.DIFF
)跨多个列(气候缺水 -- def_59_z_#
)按行获得最大值.条件如下:
- 如果 1 年过去了,select 第一年的赤字值。
(
def_59_z_1
). - 如果 2 年:前 2 年的最大赤字。
- 如果是 3 年:前 3 年的最大赤字。
- 如果是 4 年:前 4 年的最大赤字。
- 如果 5 或更多 年:前 5 年的最大值。
但是,当我包含一个条件时,我无法提取行式最大值。有几个现有的帖子可以解决按行的最小值和最大值(示例 apply
但当我涉及多个列以及条件要求时,我无法找到解决方案。
下面的代码只是 returns 新列 def59_z_max15
中的 3.5,这是数据帧中出现的最大值 -- except 当 YEAR.DIFF
为1,此时直接返回def_50_z_1
。但对于所有其他条件,我想要 0.98、0.67、0.7、1.55、1.28 —— 反映指定列的行最大值的值。 Link 采样数据 here。我怎样才能做到这一点?
我感谢 any/all 的建议!
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))))))
将此函数放入 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
一个选项是在循环中分别为每组条件获取 pmax
(按行 max
- 矢量化)(map
- 如果 'YEAR.DIFF' 是 1,select 只有 'def_59_z_1',对于 2,获取 'def_59_z_1' 和 'def_59_z_2' 的最大值,...,对于 5,最大值 'def_59_z_1' ] 到 'def_59_z_5'、coalesce
列,并将 NA
的其余部分替换为所有“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")