Используя семейство apply в R, чтобы передать каждую строку 2-столбцового фрейма данных в созданную мной функцию? - PullRequest
3 голосов
/ 10 апреля 2020

У меня есть небольшой фрейм данных с двумя столбцами: 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)
}

fp и fn означают то же, что и в df. В этой функции bayesrule я оставил значение по умолчанию для baserate из .03. Мой вопрос: как я могу написать некоторый код R - вероятно, используя семейство функций apply, я полагаю, но, возможно, что-то еще - чтобы передать каждую строку в значении df для fp и fn на соответствующее место в функции bayesrule, что дает мне три вычисления правила Байеса (каждое с тем же значением по умолчанию baserate, равным .03)?

Я просмотрел похожие посты в SX и подошел довольно близко, но я просто стесняюсь этого. Я подошел так близко:

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

Но не ближе.

Ответы [ 2 ]

3 голосов
/ 10 апреля 2020

Как правило, если функция не векторизована и зависит от нескольких параметров длины> 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 комментарии). Таким образом, он может быть непосредственно применен

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 он циклически обрабатывается по каждому столбцу

2 голосов
/ 10 апреля 2020

Здесь вам не нужно ничего делать по строкам:

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

Поскольку внутренняя математика уже готова к векторизованной эффективности R, вы можете передавать векторы. Это будет гораздо эффективнее (вызов bayesrule один раз ), чем пытаться вызвать его один раз в строке.

...