在整个行上逐行使用purrr而不是apply()

时间:2019-05-10 08:54:58

标签: r apply purrr

我想用apply()函数替换purrr(及其派生词)。

我有一个像这样的data.frame:

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

我想逐行应用两个函数:min(x, na.rm = T)which.min(x),然后将结果作为数据帧返回。

如果我知道有多少列,我可以做例如这个:

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

如何使pmap()或其他任何purrr函数像apply()一样将整行作为参数?

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


我可能只是错过了功能或技巧。感谢您的帮助。

3 个答案:

答案 0 :(得分:3)

如果您使用省略号,则您的解决方案将适用于所有列。

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

答案 1 :(得分:2)

一种可能是:

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

或者,如果您只想保留最后两列:

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

答案 2 :(得分:1)

不是purrr解决方案,而是data.table oneliner。

library(data.table)

dt <- fread("row V1 V2 V3
1 NA  2  3
2  2 NA  3
3  3  3 NA")

melt(dt, id.vars = "row")[ , .SD[which.min(value)], by = row]
   row variable value
1:   1       V2     2
2:   2       V1     2
3:   3       V1     3