看到您对其他解决方案感到好奇..
这里我留给你一个更面向tidyverse的解决方案。
library(purrr)
library(dplyr)
mtcars %>% pmap_dfr(~c(...) %>% replace(rank(desc(.)) > 3, NA))
#> # A tibble: 32 x 11
#> mpg cyl disp hp drat wt qsec vs am gear carb
#> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 21 NA 160 110 NA NA NA NA NA NA NA
#> 2 21 NA 160 110 NA NA NA NA NA NA NA
#> 3 22.8 NA 108 93 NA NA NA NA NA NA NA
#> 4 21.4 NA 258 110 NA NA NA NA NA NA NA
#> 5 18.7 NA 360 175 NA NA NA NA NA NA NA
#> 6 NA NA 225 105 NA NA 20.2 NA NA NA NA
#> 7 NA NA 360 245 NA NA 15.8 NA NA NA NA
#> 8 24.4 NA 147. 62 NA NA NA NA NA NA NA
#> 9 NA NA 141. 95 NA NA 22.9 NA NA NA NA
#> 10 19.2 NA 168. 123 NA NA NA NA NA NA NA
#> # ... with 22 more rows
作为一个概念,它类似于base R 解决方案,但它应该(或至少尝试)更具“功能性”并希望具有可读性。即使选择的解决方案看起来非常好。
编辑。
回答您关于更多信息的评论..
应该知道~可以帮助你编写更紧凑的匿名函数。
代替:
mtcars %>% pmap_dfr(~c(...) %>% replace(rank(desc(.)) > 3, NA))
你也可以写:
mtcars %>% pmap_dfr(function(...) c(...) %>% replace(rank(desc(.)) > 3, NA))
这三个点基本上将您提供给函数的所有输入聚集在一起。我没有为每个输入编写一个变量,而是使用... 将它们全部包含在内。
pmap 将列表列表或向量列表作为第一个参数。
在这种情况下,它需要一个 data.frame,它实际上是一个相同长度的向量列表。
然后,pmap 为函数提供列表中每个向量的第 i 个元素。
... 拦截所有第 i 个元素,c() 创建这些元素的唯一向量。
函数本身只会以与公认解决方案非常相似的方式替换该向量中的 NA。我使用了rank,因为在我看来它更容易阅读,但我想这是风格问题。
pmap 总是返回一个列表。那就是你可以使用pmap_dfr 来返回一个数据框。具体来说,您希望通过将最终结果的每个向量绑定为行来创建一个数据框(这解释了最后的 r)。
查看?pmap了解更多信息。