Установка R в Ubuntu. Как сравнивать векторы, элементы векторов

💖 Нравится? Поделись с друзьями ссылкой

Запуск R скриптов в режиме Embedded дает следующие возможности:

  • позволяет пользователям языка R запускать существующие скрипты R в стандартных приложениях R, а также приложениях, использующих SQL
  • запуск R скриптов осуществляется "рядом" с данными. Эти скрипты могут содержать как стандартные пакеты, так и расширенные из репозитория CRAN
  • работа в СУБД позволяет использовать управляемый пользователем или СУБД параллелизм

Этот режим очень гибкий и также может быть дополнительно оптимизирован за счет использования прозрачного переписывания функций R в функции движка СУБД Oracle.

Использованием генерации XML в Embed R-SQL API позволяет формировать графы на R и встраивать результаты работы в панели OBIEE и документы Publisher.

Функции для запуска Embedded R из стандартной среды R

Oracle разработал несколько функций в пакете ORE, которые позволяют взять готовый скрипт и передать его для исполнения на сторону СУБД.

Интерфейс R для Embedded R позволяет не только запускать скрипты R ближе к базе данных, но также интерактивно тестировать их перед внедрением в интерфейс SQL.

Интерфейс R для Embedded R состоит из следующего набора функций (каждая полезна в своей ситуации):

ore.doEval() Запускает переданный скрипт R в базе и не позволяет передавать входные данные или параметры. Она просто возвращает ore.frame или сериализованный объект R
ore.tableApply() Получает на вход таблицу (ore.frame), которая целиком подается на вход функции. Подобно doEval() она может возвращать ore.frame или сериализованный объект R
ore.rowApply() Позволяет указать количество строк, с которыми будет работать функция (chunk size). Функция вызывается в параллели несколькими процессам, если разрешено запускать несколько R-движков в СУБД. Результатом является список результатов для каждого chunk.
ore.groupApply() Разбивает поданные данные на части по значениям соответствующего столбца, а затем запуска переданный скрипт R для каждой секции в параллели. Результатом является список результатов для каждого уникального значения столбца.
ore.indexApply() ????
ore.scriptCreate() Создает именованный скрипт R в репозитории СУБД. Эти именованные сприпты могут быть использованы в других R скриптах, работающих в режиме R Embedded
ore.scriptDrop() Удаляет именованный скрипт R

Простые примеры с doEval

Давайте напишем простую R-программу. Она будет создавать одномерный массив (вектор в терминах R). Вектор будет содержать числа от 1 до 10, затем по будет создаваться таблица (фрейм в терминах R), который будет содержать в первом столбце значения из созданного вектора, а во втором столбце то же самое значение, деленное на 10. На R это будет вот так:

id <- seq(10)
frame1 <- data.frame(id = id, res = id / 10)

Результатом работы будет

ORE> frame1
id res
1 1 0.1
2 2 0.2
3 3 0.3
4 4 0.4
5 5 0.5
6 6 0.6
7 7 0.7
8 8 0.8
9 9 0.9
10 10 1.0

Теперь мы оборачиваем все это в функцию и вызываем ее в doEval:

frame1 <- ore.doEval(
function (num = 10, scale = 10)
{
id <- seq(num)
data.frame(id = id, res = id / scale)
}
)

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

В предыдущем примере мы использовали сгенерированные данные. Это не очень интересно. В этом примере мы посмотрим, как загрузить данные из Oracle. Это делается средствами пакета ORE. Затем мы применим линейную регрессию для прогнозирования. Если бы мы запускали скрипт на стороне среды R, то это было бы так:

library(ORE)
dat <- ore.pull(ONTIME_S)
mod <- lm(ARRDELAY ~ DISTANCE + DEPDELAY, dat)

Оборачиваем в функцию и передаем на вход в doEval:

mod <- ore.doEval(
function()
{
library(ORE)
ore.connect (user="RUSER", sid="orcl", host="aryndin-ru", password="oracle",all=TRUE)
dat <- ore.pull(ONTIME_S)
lm(ARRDELAY ~ DISTANCE + DEPDELAY, dat)
});
mod_local<-ore.pull(mod)

Использование ore.tableApply

Функция tableApply обычно используется, если нам нужно построить модель по всему объему данных.

Возьмем пример с использованием GLM Regression Model. На обычном R это будет выглядеть вот так:

ore.connect (user="RUSER", sid="orcl", host="aryndin-ru", password="oracle",all=TRUE)
x <- ore.pull(ONTIME_S[,c("ARRDELAY","DISTANCE","DEPDELAY")])
mod <- glm(ARRDELAY ~ DISTANCE + DEPDELAY, data=x, family=gaussian())

Наши действия состоят в том, чтобы подключиться к базе (ore.connect) и взять столбцы "ARRDELAY","DISTANCE","DEPDELAY" из таблицы ONTIME_S. Затем мы просто вызывает алгоритм GLM Regression Model с функцией gaussian.

В случае с Oracle R Enterprise мы некоторые значения (таблицу и функцию) передадим через параметры:

modCoef <- ore.tableApply(
ONTIME_S[,c("ARRDELAY","DISTANCE","DEPDELAY")],
family=gaussian(),
function(x, family) {
mod <- glm(ARRDELAY ~ DISTANCE + DEPDELAY,
data=x, family=family)
});

Давайте разберем, что происходит. Первым делом мы отбираем 3 столбца, которые будут поданы на вход алгоритму (ONTIME_S[,c("ARRDELAY","DISTANCE","DEPDELAY")]). Они будут переданы в функцию как параметр X. Мы также указываем функцию gaussian. Все остальное осталось тем же.

Использование ore.rowApply

Функция rowApply полезна, если построенную ранее модель нужно применить к набору данных (scoring). В этом случае нам необязательно вытаскивать весь объем данных в память, а можно просто выполнять построчную обработку.

Ниже довольно простой пример для линейной регрессии. Сначала мы строим модель на прогнозирования столбца ARRDELAY на основе данных за 5-ый месяц.

ontime <- ore.pull(ONTIME_S)
mod <- lm(ARRDELAY ~ DISTANCE + DEPDELAY, data=ontime)

Затем создаем новый новый data frame с дополнительным столбцом PRED_DELAY, который заполняется с помощью построчного (по 1000 строк за раз) применения ранее построенной модели:

ONTIME_S2 <- ONTIME[,c("ARRDELAY","DEPDELAY","DISTANCE")]
ONTIME_S2$PRED_DELAY <- 0
res <- ore.rowApply(ONTIME,
mod = mod,
function(dat,mod) cbind(dat, predict(mod, dat)),
FUN.VALUE = ONTIME_S2, rows=1000)

Использование ore.groupApply

Функция groupApply используется, если нужно построить несколько однотипных моделей данных. и каждая модель строится параллельно с другими, но по своей группе данных.

Ниже пример использования groupApply для построения нескольких моделей. Каждая модель будет отвечать за своей аэропорт (INDEX=ONTIME_S$DEST):

modList <- ore.groupApply(
ONTIME_S,
INDEX=ONTIME_S$DEST,
function(dat) {
library(biglm)
biglm(ARRDELAY ~ DISTANCE + DEPDELAY, dat)
});
modList_local <- ore.pull(modList)
summary(modList_local$BOS) ## return model for BOS

Интересный пример использования ORE для отрисовки графики

Вот такая команда позволяет нам запустить R-функцию для генерации PDF-документа с графиком на стороне сервер баз данных Oracle

ore.doEval(function () {
pdf(“c:/temp/my_file.pdf")
set.seed(25)
x <- rchisq(1000, df = 3)
## Compare data with a model distribution
qqplot(x, qchisq(ppoints(x), df = 3));
abline(0,1, col = 2, lty = 2)
hist(x, freq = FALSE, ylim = c(0, 0.25))
curve(dchisq(x, df = 3), col = 2, lty = 2,
lwd = 2, add = TRUE)
dev.off()
TRUE})

Будет сгенерирован вот такой PDF-документ

Заключение

Oracle R Enterprise позволяет запускать готовые R-скрипты на стороне сервера баз данных вообще их не меняя. Это очень полезно в следующих случаях:

  • Пользовательский компьютер обладает меньшей памятью, чем сервер. Это принципиально позволяет запустить R-скрипты на гораздо большем объеме данных.
  • Необходимо использовать встроенный параллелизм базы данных для повышения скорости работы R.
  • Нужно исключить извлечения на сторону клиента данных (из соображений безопасности или из-за того, что канал между пользователем и базой данных медленный).

Единственно, что мне не очень понравилось в использовании функций ore*Apply — это плохая документированность, но, я думаю, это исправят.

Чтобы создать переменную (например, х) и присвоить ей значение (например, 1234) нужно просто ввести команду х=1234 . Теперь в любых выражениях имя переменной (в нашем случае х) будет автоматически заменено значением (у нас это 1234).

Чтобы узнать значение переменной, достаточно ввести название переменной, и R выдаст ее значение. Выглядеть это будет так:
> x=1234
> х
1234

Присваивая переменной новое значение, можно использовать старое значение, то есть создавать конструкции типа
> a=5
> a
5
> a=a+3
> a
8

Важно знать, что имена переменных могут состоять из латинских букв обоих регистров, из цифр и знаков подчеркивания (например, допустимы такие имена: a, x, x1, a_x, O_o, the_Variable_with_Long_Name, a459x4h36J4lbgT62). При этом первым символом должна обязательно являться буква! Наконец, регистр имеет значение, то есть RainForest и RainFOrest - это разные переменные.

Векторы, или как работать с рядами данных?

Что такое векторы в R?

Допустим, у нас есть группа из 5 человек, и нам надо сохранить их возраста. Можно создать пять переменных, например
> age_1=25
> age_2=20
> age_3=9
> age_4=44
> age_5=37
Однако удобнее создать одну переменную, в которую поместить все 5 значений. Такой ряд данных, объединенных одним именем, хранящийся в определенном порядке - это массив данных, или вектор.

Assign("age",c(25,20,9,44,37))
или сокращенно: age

Теперь, каждый отдельный элемент можно вызвать по его порядковому номеру в ряду, например, четвертый элемент можно получить так:
> age
44
С такими отдельными элементами можно производить все те же операции, что и с обычными числами

Функция append, или как добавить элементы в существующий вектор?

Допустим, в нашей группе появился еще один человек, возраст которого 31 год. Мы можем создать заново вектор age, но теперь из шести элементов вместо пяти. Однако есть другой способ - использовать функцию append:
> append(age,31)
25 20 9 44 37 31
Замечу, что мы могли бы вставить несколько значений, вспомнив про функцию c():
> append(age,c(31,33,35))
25 20 9 44 37 31 33 35

Также функция позволяет вставить элементы в любом месте вектора с помощью параметра after. По умолчанию установлено значение after=length(x), то есть элементы добавляются в конец. Но допустим, мы захотим вставить нашего шестого человека после второго:
> append(age, 31, after=2)
25 20 31 9 44 37

Операции с векторами, или что можно делать с векторами?

Можно оперировать всеми элементами вектора одновременно. Так прибавление числа к вектору равносильно прибавление этого числа к каждому элементу вектора. Или, например, чтобы вывести, сколько десяктов лет прожил каждый человек из нашего примера, можно сделать так:
> age/10
2.5 2.0 0.9 4.4 3.7

Аналогично со сложением, вычитанием и другими операциями, описанными в пункте про

Как сравнивать векторы, элементы векторов?

Допустим, нужно выяснить, какие элементы вектора (пусть будет тот же age) больше определенного числа (например, кто из нашей маленькой выборки совершеннолетний). R для каждого элемента скажет, выполняется ли условие, то есть TRUE (верно) или FALSE (не верно) Выглядеть будет примерно так:
>age
25 20 31 9 44 37
> age >= 18
TRUE TRUE FALSE TRUE TRUE

Но может понадобиться получить один ответ, например, верно ли, что все элементы соответствуют условию? или есть ли вообще элементы, соответствующие условию? Для этого используем две функции, соответственно, all() и any()

all(x1,x2,...,xn) - ответит на вопрос, верно ли, что все условия (x1, x2, ... и xn) верны? то есть это логическая конъюнкция. Например:
> all (age >= 7, age TRUE
# действительно, все испытуемые не младше семи и младше шестидесяти
> all (age >=18, 1 > 0)
FALSE
# хотя единица, конечно, больше нуля, но среди наших испытуемых есть один девятилетний, поэтому не верно

any(x1,x2,...,xn) - ответит на вопрос, есть ли среди условий (x1, x2, ..., xn) хоть одно верное? то есть это логическая дизъюнкция. Пример:
> any (age >=18, 1 > 0)
TRUE

Наконец, можно сравнивать между собой два вектора. Но для этого нужно либо чтобы длина большего была кратна длине меньшего либо чтобы длины были равны. Примеры:
> a > a > b
FALSE FALSE FALSE TRUE TRUE

Как задать последовательность чисел?

  • оператор:
  • seq(from,to,by,length,along) - создает последовательность, начиная с from, заканчивая to с шагом by. Можно задать длину ряда параметром length или приравнять по длине к другому вектору along . Аргументы: from, to, by, length, along (такой же длины как...)
  • rep(a, times, each) - повторять вектор a times раз или each раз каждый элемент a. Аргументы: вектор, times, each

Сортировка

  • sort(v,increasing) - сортирует вектор v; increasing - булев, true - по возрастанию, false - по убыванию, можно вместо этого написать increasing=decreasing;
  • order()

Вы можете использовать system() и Rscript для запуска сценария как асинхронного фонового процесса:

system ("Rscript -e "source(\"your-script.R\")"" , wait = FALSE ) ... save.image ("script-output.RData" ) cat ("Script completed\n\n" )

Надеюсь это поможет!

Я хочу выполнить R-сценарий в фоновом режиме с консоли R.

С консоли я обычно запускаю R-скрипт как источник ("~ / .active-rstudio-document). Мне нужно подождать, пока скрипт не будет завершен, чтобы продолжить работу. Вместо этого я хочу, чтобы R работал в фоновом режиме, пока я могу продолжить работу в консоли. Также я должен быть как-то уведомлен, когда R завершает команду источника. Возможно ли это в R?

Это может быть весьма полезно, поскольку мы часто видим, что работа занимает много времени.

PS - Я хочу, чтобы исходный скрипт работал в том же пространстве памяти, а не в новом. Поэтому решения, такие как fork, system и т. Д., Не будут работать для меня. Я вижу, могу ли я запустить R-скрипт как отдельный поток, а не отдельный процесс.

При работе с R скриптом может потребоваться обновлять его автоматически. Пакет “taskscheduleR” помогает настроить расписание для запуска R скрипта в Windows Task Schedule ежедневно, еженедельно, каждые N минут, после запуска Windows и так далее.

  1. Устанавливаем пакет “taskscheduleR” library(devtools) install.packages("devtools") install_github("jwijffels/taskscheduleR") library(taskscheduleR)

    Используем пакет «devtools», который позволяет скачивать и устанавливать пакеты напрямую с GitHub.

  2. Далее для настройки запуска скрипта можно воспользоваться либо интерактивной настройкой через форму, либо написав пару строк кода.

Настройка расписания R скрипта в Task Scheduler через Addins:

Настройка расписания R скрипта через функции пакета taskscheduleR:

Функции пакета:

  • Получить список всех задач в Windows Task Sheduler
  • Удалить задачу из Windows Task Sheduler
  • Добавить задачу запуска R скрипта
    • Доступны следующие расписания: ‘ONCE’, ‘MONTHLY’, ‘WEEKLY’, ‘DAILY’, ‘HOURLY’, ‘MINUTE’, ‘ONLOGON’, ‘ONIDLE’
## Указываем название файла R скрипта для последующей работы с ним myscript <- system.file("extdata", "helloworld.R", package = "taskscheduleR") ## Запуск скрипта разово через 35 секунд taskscheduler_create(taskname = "myscript", rscript = myscript, schedule = "ONCE", starttime = format(Sys.time() + 35, "%H:%M")) ## Запуск скрипта ежедневно в 10:15, начиная с завтрашнего дня ## Важно: необходимо поменять формат даты, если он не совпадает с тем, что стоит на компьютере (пример: %m/%d/%Y) taskscheduler_create(taskname = "myscriptdaily", rscript = myscript, schedule = "DAILY", starttime = "10:15", startdate = format(Sys.Date()+1, "%d/%m/%Y")) ## Запуск скрипта каждую неделю в 10:15 по понедельникам taskscheduler_create(taskname = "myscript_mon", rscript = myscript, schedule = "WEEKLY", starttime = "10:15", days = "MON") ## Запуск каждые 5 минут, начиная с 10:15 taskscheduler_create(taskname = "myscript_5min", rscript = myscript, schedule = "MINUTE", starttime = "10:15", modifier = 5) ## Получить data.frame со всеми задачами tasks <- taskscheduler_ls() str(tasks) ## Удалить задачи taskscheduler_delete(taskname = "myscript") taskscheduler_delete(taskname = "myscriptdaily") taskscheduler_delete(taskname = "myscript_,mon") taskscheduler_delete(taskname = "myscript_5min") taskscheduler_delete(taskname = "myscript_withargs_a") taskscheduler_delete(taskname = "myscript_withargs_b")

На что обращаем внимание:

  • Формат даты . Он должен совпадать с форматом даты на компьютере. В противном случае получим либо ошибку настройки расписания запуска скрипта, либо совсем другую дату.
  • Активность компьютера . Компьютер должен быть включен в момент запуска скрипта
  • Наличие других расписаний скрипта . При настройке нового расписания с тем же названием, предыдущее расписание удаляется.
Рассказать друзьям