在大于 R 中另一列的数组中查找最小值
Find minimum value in an array that is larger than another column in R
我需要找到比另一列中的值大的三列的最小值。假设这五个人在一年中的不同月份进入医院,并且他们在住院前后多次心脏病发作。我需要住院后的第一次心脏病发作。
id<-c(100,105,108,200,205)
hosp<-c(3,5,2,6,2)
attack1<-c(1,6,3,4,1)
attack2<-c(4,7,9,10,NA)
attack3<-c(5,10,NA,NA,NA)
out<-c(7,12,11,12,9)
data <- data.frame(id,hosp,attack1,attack2,attack3,out)
id hosp attack1 attack2 attack3 out
1 100 3 1 4 5 7
2 105 5 6 7 10 12
3 108 2 3 9 NA 11
4 200 6 4 10 NA 12
5 205 2 1 NA NA 9
所以数据最终应该看起来像
id hosp attack1 attack2 attack3 out afterh
1 100 3 1 4 5 7 4
2 105 5 6 7 10 12 6
3 108 2 3 9 NA 11 3
4 200 6 4 10 NA 12 10
5 205 2 1 NA NA 9 NA
这是我的尝试,但没有成功:
min_f<-function(a){
x<-min(a[a>hosp])
}
data %>% mutate_if(vars(attack1,attack2,attack3),min_f())
您可以使用以下解决方案。
- 这里 c(...) 指的是数据集中每一行中的所有变量,我只选择了以
attack
开头的变量
- 然后我在每一行中只选择那些大于
hosp
对应值的值,因为你正在寻找第一个大于 hosp
值的值,我使用first
函数提取
..2
也指每一行中第二个变量hosp
的值
library(dplyr)
library(purrr)
data %>%
mutate(afterh = pmap_dbl(., ~ {x <- c(...)[3:5];
first(sort(x[x > ..2]))}))
id hosp attack1 attack2 attack3 out afterh
1 100 3 1 4 5 7 4
2 105 5 6 7 10 12 6
3 108 2 3 9 NA 11 3
4 200 6 4 10 NA 12 10
5 205 2 1 NA NA 9 NA
作为亲爱的@Greg 先生在非常大的数据集中提到的替代方案,我们可以使用 min
函数代替 first(sort))
组合,以确保更快的以下评估时间解决方案。如果没有像最后一行那样大于 hosp
的值,min
函数将 return Inf
所以我确保它将 return 值 0
相反,您可以使用您喜欢的值更改它:
data %>%
mutate(afterh = pmap_dbl(., ~ {x <- c(...)[3:5];
out <- min(x[x > ..2], na.rm = TRUE);
if(!is.finite(out)) 0 else out}))
id hosp attack1 attack2 attack3 out afterh
1 100 3 1 4 5 7 4
2 105 5 6 7 10 12 6
3 108 2 3 9 NA 11 3
4 200 6 4 10 NA 12 10
5 205 2 1 NA NA 9 0
data %>%
# Nest attack columns
nest(attacks = starts_with('attack')) %>%
# Only one row at a time
rowwise() %>%
# Find first instance for each row
mutate(afterh = first(attacks[attacks > hosp])) %>%
# Unnest attacks
unnest(attacks)
几乎相似的答案,但仅使用 dplyr
library(dplyr, warn.conflicts = F)
data %>% rowwise() %>%
mutate(afterh = {xx <- select(cur_data(), starts_with('attack')); first(xx[xx > hosp])})
#> # A tibble: 5 x 7
#> # Rowwise:
#> id hosp attack1 attack2 attack3 out afterh
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 100 3 1 4 5 7 4
#> 2 105 5 6 7 10 12 6
#> 3 108 2 3 9 NA 11 3
#> 4 200 6 4 10 NA 12 10
#> 5 205 2 1 NA NA 9 NA
由 reprex package (v2.0.0)
创建于 2021-06-12
我需要找到比另一列中的值大的三列的最小值。假设这五个人在一年中的不同月份进入医院,并且他们在住院前后多次心脏病发作。我需要住院后的第一次心脏病发作。
id<-c(100,105,108,200,205)
hosp<-c(3,5,2,6,2)
attack1<-c(1,6,3,4,1)
attack2<-c(4,7,9,10,NA)
attack3<-c(5,10,NA,NA,NA)
out<-c(7,12,11,12,9)
data <- data.frame(id,hosp,attack1,attack2,attack3,out)
id hosp attack1 attack2 attack3 out
1 100 3 1 4 5 7
2 105 5 6 7 10 12
3 108 2 3 9 NA 11
4 200 6 4 10 NA 12
5 205 2 1 NA NA 9
所以数据最终应该看起来像
id hosp attack1 attack2 attack3 out afterh
1 100 3 1 4 5 7 4
2 105 5 6 7 10 12 6
3 108 2 3 9 NA 11 3
4 200 6 4 10 NA 12 10
5 205 2 1 NA NA 9 NA
这是我的尝试,但没有成功:
min_f<-function(a){
x<-min(a[a>hosp])
}
data %>% mutate_if(vars(attack1,attack2,attack3),min_f())
您可以使用以下解决方案。
- 这里 c(...) 指的是数据集中每一行中的所有变量,我只选择了以
attack
开头的变量
- 然后我在每一行中只选择那些大于
hosp
对应值的值,因为你正在寻找第一个大于hosp
值的值,我使用first
函数提取 ..2
也指每一行中第二个变量hosp
的值
library(dplyr)
library(purrr)
data %>%
mutate(afterh = pmap_dbl(., ~ {x <- c(...)[3:5];
first(sort(x[x > ..2]))}))
id hosp attack1 attack2 attack3 out afterh
1 100 3 1 4 5 7 4
2 105 5 6 7 10 12 6
3 108 2 3 9 NA 11 3
4 200 6 4 10 NA 12 10
5 205 2 1 NA NA 9 NA
作为亲爱的@Greg 先生在非常大的数据集中提到的替代方案,我们可以使用 min
函数代替 first(sort))
组合,以确保更快的以下评估时间解决方案。如果没有像最后一行那样大于 hosp
的值,min
函数将 return Inf
所以我确保它将 return 值 0
相反,您可以使用您喜欢的值更改它:
data %>%
mutate(afterh = pmap_dbl(., ~ {x <- c(...)[3:5];
out <- min(x[x > ..2], na.rm = TRUE);
if(!is.finite(out)) 0 else out}))
id hosp attack1 attack2 attack3 out afterh
1 100 3 1 4 5 7 4
2 105 5 6 7 10 12 6
3 108 2 3 9 NA 11 3
4 200 6 4 10 NA 12 10
5 205 2 1 NA NA 9 0
data %>%
# Nest attack columns
nest(attacks = starts_with('attack')) %>%
# Only one row at a time
rowwise() %>%
# Find first instance for each row
mutate(afterh = first(attacks[attacks > hosp])) %>%
# Unnest attacks
unnest(attacks)
几乎相似的答案,但仅使用 dplyr
library(dplyr, warn.conflicts = F)
data %>% rowwise() %>%
mutate(afterh = {xx <- select(cur_data(), starts_with('attack')); first(xx[xx > hosp])})
#> # A tibble: 5 x 7
#> # Rowwise:
#> id hosp attack1 attack2 attack3 out afterh
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 100 3 1 4 5 7 4
#> 2 105 5 6 7 10 12 6
#> 3 108 2 3 9 NA 11 3
#> 4 200 6 4 10 NA 12 10
#> 5 205 2 1 NA NA 9 NA
由 reprex package (v2.0.0)
创建于 2021-06-12