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

5
我希望用 purrr 函数替换 apply() 及其衍生函数。
我有一个像这样的 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个回答

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

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"))

1
你可以使用 transmute 仅保留最后几行。 - Jet

1
不是一个 purrr 解决方案,而是一个 data.table 一行代码。
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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接