which.min
我在使用dplyr 管道内部函数时遇到了一些麻烦solution (*)
,我正在寻找一种更紧凑、更优雅的方式来实现这一点
- 可重现的例子
library(dplyr)
data=data.frame(s1=c(10,NA,5,NA,NA),s2=c(8,NA,NA,4,20),s3=c(NA,NA,2,NA,10))
data
#> s1 s2 s3
#> 1 10 8 NA
#> 2 NA NA NA
#> 3 5 NA 2
#> 4 NA 4 NA
#> 5 NA 20 10
- 最小值:
在这里min(x,na.rm=TRUE)
我可以提取最小值
data%>%
rowwise()%>%
mutate(Min_s=min(c(s1,s2,s3),na.rm=TRUE))
#> Warning: There was 1 warning in `mutate()`.
#> ℹ In argument: `Min_s = min(c(s1, s2, s3), na.rm = TRUE)`.
#> ℹ In row 2.
#> Caused by warning in `min()`:
#> ! no non-missing arguments to min; returning Inf
#> # A tibble: 5 × 4
#> # Rowwise:
#> s1 s2 s3 Min_s
#> <dbl> <dbl> <dbl> <dbl>
#> 1 10 8 NA 8
#> 2 NA NA NA Inf
#> 3 5 NA 2 2
#> 4 NA 4 NA 4
#> 5 NA 20 10 10
- 提取包含最小值的变量:
在这里,我无法提取哪个变量包含最小值
data%>%
rowwise()%>%
mutate(which_s=which.min(c(s1,s2,s3)))
#> Error in `mutate()`:
#> ℹ In argument: `which_s = which.min(c(s1, s2, s3))`.
#> ℹ In row 2.
#> Caused by error:
#> ! `which_s` must be size 1, not 0.
#> ℹ Did you mean: `which_s = list(which.min(c(s1, s2, s3)))` ?
# Solution (*)
data%>%
rowwise()%>%
mutate(which_s=if(!is.na(s1)|!is.na(s2)|!is.na(s3)) {which.min(c(s1,s2,s3))} else NA )
#> # A tibble: 5 × 4
#> # Rowwise:
#> s1 s2 s3 which_s
#> <dbl> <dbl> <dbl> <int>
#> 1 10 8 NA 2
#> 2 NA NA NA NA
#> 3 5 NA 2 3
#> 4 NA 4 NA 2
#> 5 NA 20 10 3
创建于 2024-11-07,使用reprex v2.1.0
在第二行中,您将
integer(0)
在列中获得which_s
,这就是您无法无错误运行它的要点。相反,您可以先将结果存储在列表中,然后
unnest
(不要忘记启用keep_empty
参数unnest
)由此得出
如果不使用
rowwise()
,您可以在基础 R 中或使用单个mutate()
步骤执行此操作purrr::pmap_chr()
:基数R:
dplyr
/purrr
输出:
请注意,在这些答案中,@friede 的基本 R 自定义函数速度明显更快,其次是这个基本 R 方法:
我有时会错过一个好
row.which.min
功能。这个功能远非好用,而且无法与{dplyr}
-language 很好地协调工作,但在这里可能会有所帮助。v0
给予