【问题标题】:Using the apply family in R to pass each row of a 2-column dataframe to a function I made?使用 R 中的 apply 系列将 2 列数据帧的每一行传递给我创建的函数?
【发布时间】:2020-07-22 17:39:26
【问题描述】:

我有一个包含两列的小数据框:fp(误报)和fn(误报),如下所示:

falsepos <- c(.05, .25, .5)
falseneg <- c(.01, .05, .1)
x_name <- "fp"
y_name <- "fn"

df <- data.frame(falsepos,falseneg)
names(df) <- c(x_name, y_name)

我还编写了一些贝叶斯规则的改编函数,如下所示:

bayesrule <- function(baserate = .03, 
                      fp, 
                      fn) {
    output <- (baserate * (1 - fn)) / ((baserate * (1 - fn)) + ((1 - baserate) * (fp)))

    return(output)
}

fpfn 代表他们在 df 中所做的相同事情。在这个函数bayesrule 中,我为.03baserate 保留了一个默认值。我的问题是:我怎样才能编写一些R 代码-我猜可能使用apply 系列函数,但也许还有别的-传递dffp 的值中的每一行和fn 放入它们在bayesrule 函数中的相应位置,产生三个贝叶斯规则计算(每个都具有相同的默认baserate 0.03)?

我查看了 SX 中的类似帖子并且已经非常接近,但我只是害羞了这个标记。我已经接近了:

sapply(df,FUN = bayesrule,fn=df$fn, fp=df$fp)

但没有更近。

【问题讨论】:

  • bayesrule(fp=df$fp, fn=df$fn) 不起作用有什么原因吗?它提供与sapplyapplymapply 的任意组合相同的输出。

标签: r function dataframe apply


【解决方案1】:

一般来说,如果函数没有向量化,并且依赖多个长度>1的参数,我们可以使用Map/mapply

unlist(Map(bayesrule, fn = df$fn, fp = df$fp))

Vectorize 函数并应用列

Vectorize(bayesrule)(fn = df$fn, fp = df$fp)
#[1] 0.37979540 0.10516605 0.05273438

这里,函数已经被向量化了,因为函数中显示的操作是R中的向量化操作(在评论-@r2evans cmets中也提到了)。所以,可以直接应用

with(df, bayesrule(fp=fp, fn = fn))
#[1] 0.37979540 0.10516605 0.05273438

dplyr

library(dplyr)
df %>%
    mutate(new = bayesrule(fp = fp, fn = fn))

使用sapply,它会分别遍历每一列

【讨论】:

  • 感谢dplyr 位——这就是我想要结束的地方!
【解决方案2】:

您无需在此处按行执行任何操作:

bayesrule(fp=df$fp, fn=df$fn)
# [1] 0.37979540 0.10516605 0.05273438

由于内部的所有数学运算都已经为 R 的矢量化效率做好了准备,因此您可以传递矢量。这将比尝试每行调用一次更有效(调用bayesrule一次)。

【讨论】:

  • 非常感谢。以典型的方式,我认为这将比现实更复杂。这非常有效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 2021-06-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多