Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using purrr rowwise instead of apply() on whole row

Tags:

r

apply

purrr

I want to replace apply() (and it's derivatives) with a purrr function.

I have a data.frame like this one:

> df
  V1 V2 V3
1 NA  2  3
2  2 NA  3
3  3  3 NA

And I want to apply two functions rowwise: min(x, na.rm = T) and which.min(x)and return the results as a dataframe.

If I know how many columns there are I can do e.g. this:

pmap_dfr(df, function(V1, V2, V3) {data.frame(min = pmin(V1, V2, V3, na.rm = T),
                                              where = which.min(c(V1, V2, V3)))})

  min where
1   2     2
2   2     1
3   3     1

How can I make pmap() or any other purrr function take the whole row as argument just like apply()does?

func <- function(x) {data.frame(min = min(x, na.rm = T), where = which.min(x))}

> Reduce(rbind, apply(df,1, func))
    min where
V2    2     2
V1    2     1
V11   3     1


I probably just missed a feature or some trick. Thanks for your help.

like image 212
Humpelstielzchen Avatar asked May 10 '19 08:05

Humpelstielzchen


2 Answers

Your solution will work for all columns if you use an ellipsis.

pmap_dfr(df, ~data.frame(min = min(..., na.rm = TRUE), where = which.min(c(...)))) 

  min where
1   2     2
2   2     1
3   3     1
like image 51
Ritchie Sacramento Avatar answered Sep 20 '22 14:09

Ritchie Sacramento


One possibility could be:

df %>%
 mutate(min = invoke(pmin, na.rm = TRUE, .),
        where = max.col(!is.na(-.)[, 1:length(.)], ties.method = "first"))

  V1 V2 V3 min where
1 NA  2  3   2     2
2  2 NA  3   2     1
3  3  3 NA   3     1

Or if you want to keep just the last the two columns:

df %>%
 transmute(min = invoke(pmin, na.rm = TRUE, .),
        where = max.col(!is.na(-.)[, 1:length(.)], ties.method = "first"))
like image 28
tmfmnk Avatar answered Sep 16 '22 14:09

tmfmnk