Seeing that you were curious about other solutions..
Here I leave you a more tidyverse
-oriented solution.
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
As a concept, it's similar to the base
R solution, but it should (or at least tries to) be more "functional" and hopefully readable. Even if the chosen solution looks very good.
EDIT.
To answer your comment about more info..
It should be known that ~
helps you writing more compact anonymous functions.
instead of:
mtcars %>% pmap_dfr(~c(...) %>% replace(rank(desc(.)) > 3, NA))
you could also write:
mtcars %>% pmap_dfr(function(...) c(...) %>% replace(rank(desc(.)) > 3, NA))
Those three dots basically gather all together the input you're providing to your function. Instead of writing a variable for each input, I use ...
to include them all.
pmap
takes a list of lists or a list of vectors as first argument.
In this case, it takes a data.frame which is actually a list of vector of the same length.
Then, pmap
provides the function with the i-th element of each vector of the list.
...
intercept all those i-th elements and c()
create a unique vector of those elements.
The function itself will just replace NAs in that vector in very similar way to the accepted solution. I used rank
because it seemed to me a bit easier to read, but I guess it's a matter of style.
pmap
always returns a list. That's you can use pmap_dfr
to return a dataframe instead. Specifically you want to create a dataframe by binding each vector of the final result as rows (that explains the r
at the end).
Check out ?pmap
for more info.