в R, как применить функцию, которая принимает вектор в качестве входных данных, где вектор должен быть построен из нескольких столбцов фрейма данных? - PullRequest
0 голосов
/ 22 ноября 2018

Я подозреваю, что это очевидная вещь, но я не могу понять, как это сделать, или найти любую информацию, которая подходит для моего случая в этом сообществе или в другом месте.

vs - этофрейм данных, содержащий переменные:

cs <- seq(0,1,0.2)
vs <- expand.grid(cs,cs,cs)

[Кстати, уже на этом этапе у меня есть сомнения: может ли команда expand.grid быть записана более эффективно, поскольку у меня 3 раза один и тот же вектор cs?Но ладно, не главное.]

fn - это пример функции, принимающей вектор в качестве входного (фактический намного сложнее, а вектор имеет длину 16):

fn <- function(p) {(p[1]+exp(p[2])+p[3]^2)/(sum(exp(p)))}

Теперь я хочу применить fn к vs, в основном делая вектор для передачи на fn из каждой строки vs.
Для 1 строки это очевидно:

fn(c(vs[1,1],vs[1,2],vs[1,3]))
[1] -0.3333333

Но что, если я хочу сделать это автоматически для всех строк в vs?

После ознакомления с документацией do.call показался очевидным выбором, и действительно, когда я использовал пример функции(paste), это сработало:

head(do.call(paste,vs))
[1] "0 0 0"   "0.2 0 0" "0.4 0 0"
[4] "0.6 0 0" "0.8 0 0" "1 0 0" 

Конечно, это не сработало для fn, но я подумал, что это связано с тем, что paste принимает n аргументов, тогда как моя функция принимает1 аргумент.

Вот где я застрял.Я думал, что смогу создать новый столбец, содержащий векторы, сделанные из 3 столбцов vs, а затем просто запустить на нем fn.Но я не знаю, как это сделать.Я пытался подать заявку, сделать звонок с c или с list, но безрезультатно.

Есть предложения?

Спасибо!

1 Ответ

0 голосов
/ 22 ноября 2018

Мы можем использовать apply с MARGIN в качестве 1 для циклического перемещения по строкам и применять 'fn'

out1 <- apply(vs, 1, fn)

, поскольку в функции есть только один аргумент, do.call можетне работает


Другой вариант - pmap после изменения аргументов функции с 1 на 3

library(purrr)
fn1 <- function(p1, p2, p3) {(p1+exp(p2)+p3^2)/(sum(exp(c(p1, p2, p3))))}
out2 <- pmap_dbl(setNames(vs, c('p1', 'p2', 'p3')), fn1)

Или другой вариант - создать функцию с вводомв виде набора данных с извлеченными столбцамираз

n <- 3
vs <- expand.grid(rep(list(cs), n))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...