查找数组中大于 R 中另一列的最小值

ell*_*zee 5 r rowwise

我需要找到三列中大于另一列中的值的最小值。假设这五个人在一年中的不同月份入院,他们在住院前后曾多次心脏病发作。我需要住院后第一次心脏病发作。


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
Run Code Online (Sandbox Code Playgroud)

所以数据最终应该看起来像这样

   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
Run Code Online (Sandbox Code Playgroud)

这是我的尝试,但没有成功:

min_f<-function(a){
  x<-min(a[a>hosp])
}

data %>% mutate_if(vars(attack1,attack2,attack3),min_f())
Run Code Online (Sandbox Code Playgroud)

Ano*_*n R 4

您可以使用以下解决方案。

  • 这里 c(...) 指的是数据集中每一行中的所有变量,我只选择了那些以attack
  • 然后我只选择那些大于hosp每行中相应值的值,并且由于您正在寻找第一个大于hosp我使用first函数来提取该值的值
  • ..2hosp还指每行中第二个变量的值
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
Run Code Online (Sandbox Code Playgroud)

作为亲爱的 @Greg 先生在非常大的数据集中提到的替代方案,我们可以使用min函数代替first(sort))组合来确保以下解决方案的评估时间更快。如果没有大于hosp最后一行min函数返回的值Inf,因此我确保它会返回该值,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
Run Code Online (Sandbox Code Playgroud)