Для установка библиотек необходимо наличие выхода в Интернет.
Настройка RStudio для прокси-сервера
1. Установить прокси-сервер (для скачивания библиотек): ввести в консоли две команды
Sys.setenv(http_proxy=“http://proxy.bsu:3128/”)
Sys.setenv(http_proxy_user=“ask”)
Создание отчетов с помощью R Markdown
Установливаются необходимые библиотеки… (при первом использовании)
Набрать документ (правила набора: нажать на верхней части окна редактора на знак вопроса, выбрать “Markdown Quick Reference”)
Далее нажать в выпадающем списке “Knit …” выбрать тип выходного документа (html, word, pdf)
Компиляция документа…
Загрузка установленной библиотеки
library(pname)
Очистить консоль - Ctrl+“L”
Ввод предыдущей команды - Стрелка ВВЕРХ
Выполнить выделенный код (для выполнения строки кода в файлах с расширениями .R и .Rmd) - Ctrl+Enter
#текущая рабочая директория
getwd()
## [1] "C:/temp/RWorkspace/course"
#установка рабочей директории
setwd("C:/temp/RWorkspace")
#установка числа десятичных разрядов при выводе на консоль
options(digits=4)
#Поиск по точному названию функции
?options
## starting httpd help server ... done
#Поиск функции по частичному совпадению
apropos("solve")
## [1] "backsolve" "forwardsolve" "qr.solve" "solve"
## [5] "solve.default" "solve.qr"
#Вывод в текстовый файл
sink("log.txt")
print("Hello from R!")
## [1] "Hello from R!"
#Возвращение вывода на консоль
sink()
#Сохранение истории комманд
#savehistory(file="commands.R")
#Выполнение всех сохраненных комманд
#для того, чтобы видеть комманды - ввести опцию echo=T
#source("commands.R")
x=1;y=c(1,2,3)
#Просмотр списка текущих объектов (переменных)
ls()
## [1] "linmod" "qc" "res" "x" "y"
#C отображением скрытых переменных
ls(all.names=TRUE)
## [1] ".CourseraLogin" ".Random.seed" "linmod" "qc"
## [5] "res" "x" "y"
#Удаление переменной
rm(x)
#Удаление всех переменных
rm(list=ls())
x=1;y=c(1,2,3); z="Hello from R"
#Сохранить заданные переменные
save(x, y,z, file = "xyz.RData")
#Сохранить все переменные
save(list=ls(), file = "all.RData")
#Сохранить все рабочее пространство
save.image() # ~ save(list = ls(all = TRUE), file = ".RData")
#Загрузить переменные из файла
load(file = "xyz.RData")
#Новый стиль
x=10
#Для совместимости с первыми версиями R и языком S
x<-10
#Аналогично предыдущему
10->x
# Аналогично с помощью функции
assign("x",10)
#Операция присваивания - тоже функция
`=`(x,10)
Арифметические операции и математические функции
angle=60
sin(angle*pi/180)+floor(2*3+3^11-sqrt(10)) #pi - константа
## [1] 177150
#целая часть от деления
10 %/% 3
## [1] 3
#остаток от деления
10 %% 3
## [1] 1
Арифметические операции - тоже функции
`+`(2,2)
## [1] 4
Операции с комплексными числами
sqrt(-17)
## Warning: созданы NaN
## [1] NaN
sqrt(-17+0i)
## [1] 0+4.123i
#c помощью оператора ":"
(x=1:10)
## [1] 1 2 3 4 5 6 7 8 9 10
#с помощью функции c()
#числовой вектор
angle=c(30,60,90); print(angle)
## [1] 30 60 90
#получить длину вектора
length(angle)
## [1] 3
#вектор из строк
(angle.names=c("thirty","sixty","ninety"))
## [1] "thirty" "sixty" "ninety"
rad=angle*pi/180
rad=c(rad,pi,rad)
print(rad)
## [1] 0.5236 1.0472 1.5708 3.1416 0.5236 1.0472 1.5708
#Использования имени функции для пользовательской переменной
с=1;c
## function (..., recursive = FALSE) .Primitive("c")
#но
(c(1,2,3))
## [1] 1 2 3
#вектор нулевой длины
x=numeric(0)
print(x)
## numeric(0)
rad=angle*pi/180
print(rad)
## [1] 0.5236 1.0472 1.5708
(x=rad^2+1)
## [1] 1.274 2.097 3.467
x=1:10;y=c(1,1000)
#Значение вектора y циклически повторяются
(x+y)
## [1] 2 1002 4 1004 6 1006 8 1008 10 1010
#целочисленные: индексы
x=1:7
str(x)
## int [1:7] 1 2 3 4 5 6 7
is.integer(x)
## [1] TRUE
is.numeric(x)
## [1] TRUE
is.finite(x)
## [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE
#вещественные: введенные с помощью функции с
#данные о зарплате сотрудников
salary <- c(500, 600, 400, 650, 300,550,2000)
str(salary)
## num [1:7] 500 600 400 650 300 550 2000
is.numeric(salary)
## [1] TRUE
is.vector(salary)
## [1] TRUE
#рост сотрудников, м
height=c(1.75,1.80,1.90,1.65,1.70,1.72,1.85)
is.numeric(height)
## [1] TRUE
#имена сотрудников
name=c("Иван", "Алексей", "Александр", "Анна","Татьяна", "Валентин", "Андрей")
str(name)
## chr [1:7] "Иван" "Алексей" "Александр" "Анна" "Татьяна" ...
is.character(name)
## [1] TRUE
is.character(salary)
## [1] FALSE
is.character(as.character(salary))
## [1] TRUE
#пол сотрудников
sex <- c("male", "male", "male", "female", "female", "male", "male")
table(sex)
## sex
## female male
## 2 5
#является ли зарплата больше средней?
check=(salary >500)
str(check)
## logi [1:7] FALSE TRUE FALSE TRUE FALSE TRUE ...
is.logical(check)
## [1] TRUE
#NA : Not Available - значения нет
(z=c(1:3,NA))
## [1] 1 2 3 NA
is.na(z)
## [1] FALSE FALSE FALSE TRUE
#Пример- девушки не захотели назвать свой вес
(weight=c(82, 87, 93, NA, NA, 72, 82))
## [1] 82 87 93 NA NA 72 82
#NaN : Not a Number - значение неопределено
print(0/0)
## [1] NaN
(x=c(z,Inf-Inf))
## [1] 1 2 3 NA NaN
#тестирование на пропущенные значения
is.na(x)
## [1] FALSE FALSE FALSE TRUE TRUE
is.nan(x)
## [1] FALSE FALSE FALSE FALSE TRUE
#количественная: размер зарплаты
str(salary)
## num [1:7] 500 600 400 650 300 550 2000
#порядковая шкала: размер одежды
size=c("XLL", "S", "XL", "S", "S", "M", "L")
str(size)
## chr [1:7] "XLL" "S" "XL" "S" "S" "M" "L"
#номинальная шкала: имя
str(name)
## chr [1:7] "Иван" "Алексей" "Александр" "Анна" "Татьяна" ...
salary #весь вектор
## [1] 500 600 400 650 300 550 2000
salary[7]
## [1] 2000
#индекс может быть и к нескольким элементам сразу
salary[c(1,3,5,7)]
## [1] 500 400 300 2000
salary[1:3]
## [1] 500 600 400
#можно выбрать все кроме 7-го элемента:
salary[-7]
## [1] 500 600 400 650 300 550
#или кроме первых трех элементов
salary[-(1:3)]
## [1] 650 300 550 2000
#c помощью условного вектора
idx=salary>500; salary[idx]
## [1] 600 650 550 2000
#или короче
salary[salary>500]
## [1] 600 650 550 2000
#есть пропущенные значения
weight
## [1] 82 87 93 NA NA 72 82
#присвоим всем пропущенным средний вес человека на Земле
weight[is.na(weight)]=62
print(weight)
## [1] 82 87 93 62 62 72 82
#можно было присвоить сразу нескольким элементам
(weight=c(82, 87, 93, NA, NA, 72, 82))
## [1] 82 87 93 NA NA 72 82
weight[is.na(weight)]=c(60,62)
print(weight)
## [1] 82 87 93 60 62 72 82
#внутренние (intrinsic) атрибуты
mode(salary) #тип данных
## [1] "numeric"
length(salary) #длина вектора
## [1] 7
#увеличим длину вектора
length(salary)=10
#теперь имеем пропущенные значения
salary
## [1] 500 600 400 650 300 550 2000 NA NA NA
length(salary)=7 #прежнее значение
#атрибут "метки"
str(salary) #индексы по умолчанию - порядковые номера
## num [1:7] 500 600 400 650 300 550 2000
names(salary)=c("Иван", "Алексей", "Александр", "Анна",
"Татьяна", "Валентин", "Андрей")
#теперь имеем именованный вектор
str(salary)
## Named num [1:7] 500 600 400 650 300 550 2000
## - attr(*, "names")= chr [1:7] "Иван" "Алексей" "Александр" "Анна" ...
salary
## Иван Алексей Александр Анна Татьяна Валентин Андрей
## 500 600 400 650 300 550 2000
#и можно обращаться с помощью текстовых индексов
salary[c("Татьяна","Андрей")]
## Татьяна Андрей
## 300 2000
#получить атрибут "names" у переменной "salary"
attr(salary,"names")
## [1] "Иван" "Алексей" "Александр" "Анна" "Татьяна" "Валентин"
## [7] "Андрей"
#удалить данный атрибут
attr(salary,"names")=NULL
print(salary)
## [1] 500 600 400 650 300 550 2000
#можно придумать свои атрибуты
attr(salary,"Less 500")=salary<500
str(salary)
## atomic [1:7] 500 600 400 650 300 550 2000
## - attr(*, "Less 500")= logi [1:7] FALSE FALSE TRUE FALSE TRUE FALSE ...
attr(salary,"Less 500")<-NULL
m1=matrix(c(1,2,3,4),nrow=2,ncol=2) #достаточно только указать nrow=2 или ncol=2
#по умолчанию заполняются столбцы матрицы
m1
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
#опция byrow=T позволяет заполнять матрицу построчно
m1=matrix(c(1,2,3,4),nrow=2,byrow=T);m1
## [,1] [,2]
## [1,] 1 2
## [2,] 3 4
#значения исходного вектора циклически повторяются
x=1:3;matrix(x,nrow=2,ncol=3)
## [,1] [,2] [,3]
## [1,] 1 3 2
## [2,] 2 1 3
#нулевая матрица
matrix(0,nrow=2,ncol=3)
## [,1] [,2] [,3]
## [1,] 0 0 0
## [2,] 0 0 0
#проверка на тип данных
is.numeric(m1)
## [1] TRUE
#проверка, что объект является матрицей
is.matrix(m1)
## [1] TRUE
#представление в текстовой форме
str(m1)
## num [1:2, 1:2] 1 3 2 4
#атрибуты
dim(m1) #размерность матрицы
## [1] 2 2
ncol(m1) #количество столбцов
## [1] 2
#получение матрицы с помощью атрибута dim
m2=1:20
dim(m2)=c(4,5) #элементы вектора заносятся по столбцам
m2
## [,1] [,2] [,3] [,4] [,5]
## [1,] 1 5 9 13 17
## [2,] 2 6 10 14 18
## [3,] 3 7 11 15 19
## [4,] 4 8 12 16 20
#именование индексов матрицы
colnames(m2) #по умолчанию - нет названий столбцов
## NULL
colnames(m2)=c("a","b","c","d","e")
m2 #теперь столбцы именованные
## a b c d e
## [1,] 1 5 9 13 17
## [2,] 2 6 10 14 18
## [3,] 3 7 11 15 19
## [4,] 4 8 12 16 20
rownames(m2)=c("alpha","beta","gamma","delta")
m2
## a b c d e
## alpha 1 5 9 13 17
## beta 2 6 10 14 18
## gamma 3 7 11 15 19
## delta 4 8 12 16 20
m3=1:24
dim(m3)=c(3,4,2) # m3=array(m3,dim=c(3,4,2))
m3
## , , 1
##
## [,1] [,2] [,3] [,4]
## [1,] 1 4 7 10
## [2,] 2 5 8 11
## [3,] 3 6 9 12
##
## , , 2
##
## [,1] [,2] [,3] [,4]
## [1,] 13 16 19 22
## [2,] 14 17 20 23
## [3,] 15 18 21 24
#индексы-числа
m2[2,3]
## [1] 10
m2[c(1,2),c(3,4)]
## c d
## alpha 9 13
## beta 10 14
m2[2,] #извлечь вторую строку
## a b c d e
## 2 6 10 14 18
m2[,1:3] #извлечь первые три столбца
## a b c
## alpha 1 5 9
## beta 2 6 10
## gamma 3 7 11
## delta 4 8 12
m2[-1,] #извлечь все строки, кроме первой
## a b c d e
## beta 2 6 10 14 18
## gamma 3 7 11 15 19
## delta 4 8 12 16 20
#индексы-метки
m2["beta",]
## a b c d e
## 2 6 10 14 18
m2[,c("a","b")]
## a b
## alpha 1 5
## beta 2 6
## gamma 3 7
## delta 4 8
#индекс-матрица
(i <- array(c(1:3,3:1), dim=c(3,2)))
## [,1] [,2]
## [1,] 1 3
## [2,] 2 2
## [3,] 3 1
m2[i]
## [1] 9 6 3
#присвоить элементам матрицы значение 0
m2[i]=0;m2
## a b c d e
## alpha 1 5 0 13 17
## beta 2 0 10 14 18
## gamma 0 7 11 15 19
## delta 4 8 12 16 20
#sex <- c("male", "male", "male", "female", "female", "male", "male")
sex.f=factor(sex) #аналогично sex.f=as.factor(sex)
is.factor(sex.f)
## [1] TRUE
str(sex.f) #текстовое представление фактора - метки (labels)
## Factor w/ 2 levels "female","male": 2 2 2 1 1 2 2
labels(sex.f)
## [1] "1" "2" "3" "4" "5" "6" "7"
print(sex.f) #внешнее представление - уровни (levels)
## [1] male male male female female male male
## Levels: female male
levels(sex.f) #глаыный атрибут фактора
## [1] "female" "male"
table(sex.f) # получить частоты
## sex.f
## female male
## 2 5
plot(sex.f) #график частот
print(as.numeric(sex.f)) # факторы легко преобразуются в количественные переменные
## [1] 2 2 2 1 1 2 2
#преобразование количественной шкалы к порядковой - фактору
salary.ranges=cut(x=salary,breaks=c(0,500,2000))
str(salary.ranges)
## Factor w/ 2 levels "(0,500]","(500,2e+03]": 1 2 1 2 1 2 2
table(salary.ranges)
## salary.ranges
## (0,500] (500,2e+03]
## 3 4
#изменим атрибут "salary"
levels(salary.ranges)=c("Low","High")
print(salary.ranges)
## [1] Low High Low High Low High High
## Levels: Low High
size=c("XXL", "S", "XL", "S", "S", "M", "L")
(size.f=factor(size)) #неупорядоченный
## [1] XXL S XL S S M L
## Levels: L M S XL XXL
(ordered(size.f, levels=c("S", "M", "L", "XL", "XXL")))
## [1] XXL S XL S S M L
## Levels: S < M < L < XL < XXL
Списки содержат разнородные элементы
#лист объединяет данные всех типов
family = list(husband="Fred", wife="Mary", nchildren=3,
child.ages=c(4,7,9));family
## $husband
## [1] "Fred"
##
## $wife
## [1] "Mary"
##
## $nchildren
## [1] 3
##
## $child.ages
## [1] 4 7 9
str(family)
## List of 4
## $ husband : chr "Fred"
## $ wife : chr "Mary"
## $ nchildren : num 3
## $ child.ages: num [1:3] 4 7 9
#индексы
family["wife"] # оператор "[]" выдает то же тип данных - лист размерности 1
## $wife
## [1] "Mary"
family[2] #можно пользоваться и индексом
## $wife
## [1] "Mary"
family[["wife"]] # оператор "[[]]" выдает атомарный тип - строку
## [1] "Mary"
family$wife # $ аналогично [[]]
## [1] "Mary"
#добавим новый элемент
family$granny="Anna"
names(family) #теперь есть новый элемент "granny"
## [1] "husband" "wife" "nchildren" "child.ages" "granny"
Объединяют свойства матриц и списков
#создадим таблицу данных о сотрудниках
staff <- data.frame(v1=name,v2=salary,v3=sex.f,v4=weight, v5=height,v6=size,
stringsAsFactors = FALSE)
staff
## v1 v2 v3 v4 v5 v6
## 1 Иван 500 male 82 1.75 XXL
## 2 Алексей 600 male 87 1.80 S
## 3 Александр 400 male 93 1.90 XL
## 4 Анна 650 female 60 1.65 S
## 5 Татьяна 300 female 62 1.70 S
## 6 Валентин 550 male 72 1.72 M
## 7 Андрей 2000 male 82 1.85 L
#зададим имена переменных
names(staff)=c("name","salary","sex","weight","height","size")
staff
## name salary sex weight height size
## 1 Иван 500 male 82 1.75 XXL
## 2 Алексей 600 male 87 1.80 S
## 3 Александр 400 male 93 1.90 XL
## 4 Анна 650 female 60 1.65 S
## 5 Татьяна 300 female 62 1.70 S
## 6 Валентин 550 male 72 1.72 M
## 7 Андрей 2000 male 82 1.85 L
#скроем вес женщин
staff$weight[staff$sex=="female"]=NA
#текстовое представление
str(staff)
## 'data.frame': 7 obs. of 6 variables:
## $ name : chr "Иван" "Алексей" "Александр" "Анна" ...
## $ salary: num 500 600 400 650 300 550 2000
## $ sex : Factor w/ 2 levels "female","male": 2 2 2 1 1 2 2
## $ weight: num 82 87 93 NA NA 72 82
## $ height: num 1.75 1.8 1.9 1.65 1.7 1.72 1.85
## $ size : chr "XXL" "S" "XL" "S" ...
#присвоим каждой строке метку
row.names(staff)=letters[1:nrow(staff)];staff
## name salary sex weight height size
## a Иван 500 male 82 1.75 XXL
## b Алексей 600 male 87 1.80 S
## c Александр 400 male 93 1.90 XL
## d Анна 650 female NA 1.65 S
## e Татьяна 300 female NA 1.70 S
## f Валентин 550 male 72 1.72 M
## g Андрей 2000 male 82 1.85 L
#извлечем данные об одном сотруднике
staff[staff$name=="Иван",]
## name salary sex weight height size
## a Иван 500 male 82 1.75 XXL
#Извлечем данные по зарплатам
staff$salary
## [1] 500 600 400 650 300 550 2000
#извлечем данные о зарплате среди женщин
staff[staff$sex=="female","salary"]
## [1] 650 300
#извлечем имена работников
#оператор "[]" извлекает таблицу данных
staff["name"]
## name
## a Иван
## b Алексей
## c Александр
## d Анна
## e Татьяна
## f Валентин
## g Андрей
#оператор "[[]]" извлекает вектор
staff[["name"]]
## [1] "Иван" "Алексей" "Александр" "Анна" "Татьяна" "Валентин"
## [7] "Андрей"
#извлечем первые три строки
staff[1:3,]
## name salary sex weight height size
## a Иван 500 male 82 1.75 XXL
## b Алексей 600 male 87 1.80 S
## c Александр 400 male 93 1.90 XL
#то же самое с помощью меток
staff[c("a","b","c"),]
## name salary sex weight height size
## a Иван 500 male 82 1.75 XXL
## b Алексей 600 male 87 1.80 S
## c Александр 400 male 93 1.90 XL
#отсортируем таблицу данных по имени и зарплате
staff[order(staff$name, staff$salary), ]
## name salary sex weight height size
## c Александр 400 male 93 1.90 XL
## b Алексей 600 male 87 1.80 S
## g Андрей 2000 male 82 1.85 L
## d Анна 650 female NA 1.65 S
## f Валентин 550 male 72 1.72 M
## a Иван 500 male 82 1.75 XXL
## e Татьяна 300 female NA 1.70 S
#запишем данные о сотрудниках в файл "staff.txt" (разделитель - табуляция)
write.table(staff,"staff.txt",sep="\t",fileEncoding="UTF-8")
#удалим таблицу данных из оперативной памяти
rm(staff)
staff #данных не найдено
## Error: объект 'staff' не найден
#прочитаем заново данные
#header=TRUE: читать имена переменных (заголовки) из первой строки
#encoding="UTF-8": для чтения кириллицы (имена сотрудников)
staff=read.table("staff.txt",header=TRUE,sep="\t",encoding="UTF-8")
#просмотрим список текущих переменных
ls()
## [1] "staff"
salary # переменной "salary" нет
## Error: объект 'salary' не найден
#присоединяем таблицу данных
attach(staff)
#теперь можем обращаться к переменным из таблицы данных
salary
## [1] 500 600 400 650 300 550 2000
#отсоединяем: надо всегда делать при окончании работы
#с данной таблицей данных
detach(staff)
(s=1:10)
## [1] 1 2 3 4 5 6 7 8 9 10
print(pi:10)
## [1] 3.142 4.142 5.142 6.142 7.142 8.142 9.142
#Первый способ
(s1=seq(-3,3,0.5))
## [1] -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0
#Второй способ
(s2=seq(from=-3,to=3,by=0.5))
## [1] -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0
#Третий способ
(s3=seq(length=13,from=-3,by=0.5))
## [1] -3.0 -2.5 -2.0 -1.5 -1.0 -0.5 0.0 0.5 1.0 1.5 2.0 2.5 3.0
s=c(1,2,3)
rep(s,times=3)
## [1] 1 2 3 1 2 3 1 2 3
rep(s,each=3)
## [1] 1 1 1 2 2 2 3 3 3
x=1:2;y=3:4
#скалярное произведение (inner product)
x %*% y
## [,1]
## [1,] 11
#внешнее произведение (outer product)
x %o% y #аналогично x %*% t(y)
## [,1] [,2]
## [1,] 3 4
## [2,] 6 8
m1=m2=matrix(c(1,2,3,4),nrow=2);m1
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
#функции rbind,cbind - получение составной матрицы
rbind(m1,m2) # по строкам
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
## [3,] 1 3
## [4,] 2 4
cbind(m1,m2) # по столбцам
## [,1] [,2] [,3] [,4]
## [1,] 1 3 1 3
## [2,] 2 4 2 4
# функция t: транспонировать матрицу
t(m1)
## [,1] [,2]
## [1,] 1 2
## [2,] 3 4
#скалярное умножение матриц (аналогично для операции деления "/")
m1*m2
## [,1] [,2]
## [1,] 1 9
## [2,] 4 16
#вычислить матричное выражение
m1+m2-12*m2+1
## [,1] [,2]
## [1,] -9 -29
## [2,] -19 -39
#матричное умножение
m1 %*% m2
## [,1] [,2]
## [1,] 7 15
## [2,] 10 22
#умножить на вектор
m1 %*% 1:2
## [,1]
## [1,] 7
## [2,] 10
# crossprod(m1,m2)=t(m1)*m2
crossprod(m1,m2)
## [,1] [,2]
## [1,] 5 11
## [2,] 11 25
#диагональ маттрицы
diag(m1)
## [1] 1 4
#определитель матрицы
det(m1)
## [1] -2
#обратить матрицу
solve(matrix(c(1,2,2,5),nrow=2))
## [,1] [,2]
## [1,] 5 -2
## [2,] -2 1
#решить систему линейных уравнений с матрицей A и свободным вектором b
A=matrix(1:4,nrow=2);b=c(5,6)
solve(A,b) # лучше, чем solve(A) %*% b
## [1] -1 2
#найти собственные значения и вектора
ev=eigen(A)
ev$values #собственные значения
## [1] 5.3723 -0.3723
ev$vectors #Собственные вектора
## [,1] [,2]
## [1,] -0.5658 -0.9094
## [2,] -0.8246 0.4160
#разложение холецкого A=t(B) %*% B, A - положительно определенная
A=matrix(c(1,2,2,5),nrow=2)
(B=chol(A))
## [,1] [,2]
## [1,] 1 2
## [2,] 0 1
t(B) %*% B
## [,1] [,2]
## [1,] 1 2
## [2,] 2 5
apply, tapply, sapply, lapply
#извлечем из данных только количественные переменные
(staff.num=staff[c("salary","weight","height")])
## salary weight height
## a 500 82 1.75
## b 600 87 1.80
## c 400 93 1.90
## d 650 NA 1.65
## e 300 NA 1.70
## f 550 72 1.72
## g 2000 82 1.85
#применим функцию "mean" (среднее) к каждому столбцу
#параметр "2" означает по второму измерению (столбцу)
apply(staff.num,2,mean)
## salary weight height
## 714.286 NA 1.767
#можно применить любую другую функцию, даже анонимную
#здесь аргумент "х" принимает поочередно принимает значения
#каждого перебираемого столбца
#sd - станд. отклонение
apply(staff.num, 2, function(x) {mean(x)/sd(x)})
## salary weight height
## 1.233 NA 20.107
#пример вычисления apply по строкам
(m=matrix(1:6,nrow=3))
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
apply(m,1,sum) #подсчет суммы элементов в строке матрицы
## [1] 5 7 9
#подсчитаем макс. зарплату среди мужчин и женщин
#tapply позволяет разделить значения по переменной sex на два множества
#и применить функцию (в данном случае - max) к каждому множ. отдельно
tapply(staff$salary,staff$sex,max)
## female male
## 650 2000
#преобразуем все переменные таблицы данных в количественные
#sapply сохраняет структуру данных
sapply(staff, as.numeric)
## name salary sex weight height size
## [1,] 6 500 2 82 1.75 5
## [2,] 2 600 2 87 1.80 3
## [3,] 1 400 2 93 1.90 4
## [4,] 4 650 1 NA 1.65 3
## [5,] 7 300 1 NA 1.70 3
## [6,] 5 550 2 72 1.72 2
## [7,] 3 2000 2 82 1.85 1
#проверим, какие переменные в таблице - факторы
#результат lapply - всегда список (в отличие от sapply)
sapply(staff, is.factor)
## name salary sex weight height size
## TRUE FALSE TRUE FALSE FALSE TRUE
x=300
#результат логического выражения - скаляр
if (x>500) "Normal" else "Low"
## [1] "Low"
#если надо записать несколько команд - запись условия следующая
if(x>500){
temp="Normal"
print(temp)
} else{
temp="Low"
print(temp)
}
## [1] "Low"
#результат логического выражения - вектор
ifelse(staff$salary>500,"Normal","Low")
## [1] "Low" "Normal" "Low" "Normal" "Low" "Normal" "Normal"
#индекс поочередно выбирается из последовательности
#последовательность - вектор из элементов 1,2,...,100
s=0
for (i in 1:100){
s=s+i
}
s
## [1] 5050
#последовательность - буквы
s=""
for (c in letters){
s=paste(s,c)
}
s
## [1] " a b c d e f g h i j k l m n o p q r s t u v w x y z"
#последовательность переменные таблицы
#результат похож на lapply(staff,class)
for (var in staff){
print(class(var))
}
## [1] "factor"
## [1] "integer"
## [1] "factor"
## [1] "integer"
## [1] "numeric"
## [1] "factor"
# C помощью цикла
t0=proc.time()
s=0
for (i in 1:10^6) s=s+i
t1=proc.time()
t1-t0
## user system elapsed
## 0.38 0.00 0.38
#c помощью встроенной функции
t0=proc.time()
sum(as.numeric(1:10^6))
## [1] 5e+11
t1=proc.time()
t1-t0
## user system elapsed
## 0.06 0.00 0.06
arg1 - обязательный параметр: должен быть задан при вызове функции
arg2,arg3 - необязательные параметры, если не заданы, то используются значения по умолчанию
… - список параметров, которые могут быть далее переданы функции f0
f=function(arg1,arg2=0,arg3=“a”,…){
if(arg3==“a”){
temp=arg1+arg2
} else{
temp=f0(arg1,…)
}
return(temp)# или просто temp
}
#пример функции - staff.subset
#функция извлекает подбыборку из таблицы данных staff (обязат. аргумент)
#sex: извлекаются данные о сотрудниках определенного пола (или одновр. М и Ж)
#order: если указана переменная var, то данные перед выводом сортируются по ней
#если переменная указана, то по ней вычисляется среднее
staff.subset = function(staff, sex="all", var=FALSE,...){
#проверить,что staff действительно - таблица данных
if(!is.data.frame(staff)) stop("Invalid data")
#выбрать данные, согласно sex
if(sex=="all"){
temp=staff
}else{
#проверка, что значение параметра sex действительно есть в выборке
if (!(sex %in% staff$sex)) stop("Invalid sex")
temp=staff[staff$sex==sex,]
}
#отсоритровать по переменной var (или не сортировать)
if(var!=FALSE){
#проверить, что данная переменная есть в данных
if(!var %in% names(staff)) stop("Invalid variable")
#найти среднее по переменной var
#если были переданы дополнительные параметры в staff.subset (вместо ...),
#то они передаются в mean (также на место ...)
#распечатать среднее по данной переменной
mu=mean(temp[,var],...)
cat("mean of ", var , " = ", mu, "\n")
#отсортировать данные и вывести
#результата этой строки будет выведен как последнее вычисляемое выражение
#можно вписать эту строку в return() - результат аналогичный
temp[order(temp[[var]]),]
}else{
#также выводится как результат функции
temp #можно записать return(temp)
}
}
source(“staff_subset.R”)
Используем только, что созданную функцию
#просмотрим вначале исходную таблицу данных
staff
## name salary sex weight height size
## a Иван 500 male 82 1.75 XXL
## b Алексей 600 male 87 1.80 S
## c Александр 400 male 93 1.90 XL
## d Анна 650 female NA 1.65 S
## e Татьяна 300 female NA 1.70 S
## f Валентин 550 male 72 1.72 M
## g Андрей 2000 male 82 1.85 L
#передадим эту таблицу в функцию, остальные параметры - по умолчанию
staff.subset(staff)
## name salary sex weight height size
## a Иван 500 male 82 1.75 XXL
## b Алексей 600 male 87 1.80 S
## c Александр 400 male 93 1.90 XL
## d Анна 650 female NA 1.65 S
## e Татьяна 300 female NA 1.70 S
## f Валентин 550 male 72 1.72 M
## g Андрей 2000 male 82 1.85 L
#попробуем передать вектор вместо таблицы
staff.subset(1:10)
## Error: Invalid data
#выведем данные по мужскому полу
staff.subset(staff,"male")
## name salary sex weight height size
## a Иван 500 male 82 1.75 XXL
## b Алексей 600 male 87 1.80 S
## c Александр 400 male 93 1.90 XL
## f Валентин 550 male 72 1.72 M
## g Андрей 2000 male 82 1.85 L
#выведем данные по мужскому полу и отсортируем по зарплате
staff.subset(staff,"female","salary")
## mean of salary = 475
## name salary sex weight height size
## e Татьяна 300 female NA 1.70 S
## d Анна 650 female NA 1.65 S
#то же, только зададим явно все имена аргументов
staff.subset(staff=staff,sex="female",var="salary")
## mean of salary = 475
## name salary sex weight height size
## e Татьяна 300 female NA 1.70 S
## d Анна 650 female NA 1.65 S
#изменим порядок аргументов: третий аргумент (var) идет вторым
#в этом случае обязательно указывать название аргумента
staff.subset(staff,var="salary")
## mean of salary = 714.3
## name salary sex weight height size
## e Татьяна 300 female NA 1.70 S
## c Александр 400 male 93 1.90 XL
## a Иван 500 male 82 1.75 XXL
## f Валентин 550 male 72 1.72 M
## b Алексей 600 male 87 1.80 S
## d Анна 650 female NA 1.65 S
## g Андрей 2000 male 82 1.85 L
#второй аргумент следует первым
#остальные аргументы последовательно присваиваются оставшимся
staff.subset(sex="female",staff,"salary")
## mean of salary = 475
## name salary sex weight height size
## e Татьяна 300 female NA 1.70 S
## d Анна 650 female NA 1.65 S
#последние два аргумента следуют первыми
#третий аргумент перенаправляется к первому неприсвоенному (staff)
staff.subset(var="salary", sex="female", staff)
## mean of salary = 475
## name salary sex weight height size
## e Татьяна 300 female NA 1.70 S
## d Анна 650 female NA 1.65 S
#в качестве var зададим переменную weight (содержит пропущенные значения)
staff.subset(staff,var="weight") #среднее значение = NA
## mean of weight = NA
## name salary sex weight height size
## f Валентин 550 male 72 1.72 M
## a Иван 500 male 82 1.75 XXL
## g Андрей 2000 male 82 1.85 L
## b Алексей 600 male 87 1.80 S
## c Александр 400 male 93 1.90 XL
## d Анна 650 female NA 1.65 S
## e Татьяна 300 female NA 1.70 S
#использование mean
staff$weight #переменная weight
## [1] 82 87 93 NA NA 72 82
mean(staff$weight) #без исключения пропущенных значений
## [1] NA
mean(staff$weight,na.rm=TRUE) #c исключением пропущенных значений
## [1] 83.2
#передадим параметр na.rm=TRUE через функцию staff.subset
staff.subset(staff,var="weight",na.rm=TRUE) # параметр na.rm перенаправляется в функцию mean
## mean of weight = 83.2
## name salary sex weight height size
## f Валентин 550 male 72 1.72 M
## a Иван 500 male 82 1.75 XXL
## g Андрей 2000 male 82 1.85 L
## b Алексей 600 male 87 1.80 S
## c Александр 400 male 93 1.90 XL
## d Анна 650 female NA 1.65 S
## e Татьяна 300 female NA 1.70 S
#функция sd не является обобщенной - работает только для векторов
sd
## function (x, na.rm = FALSE)
## sqrt(var(if (is.vector(x)) x else as.double(x), na.rm = na.rm))
## <bytecode: 0x0000000008dcd060>
## <environment: namespace:stats>
#функция str является обобщенной - UseMethod("str")
str
## function (object, ...)
## UseMethod("str")
## <bytecode: 0x0000000007791790>
## <environment: namespace:utils>
#методы (реализации) функции str для раздичных типов данных
methods("str")
## [1] str.data.frame* str.Date* str.default* str.dendrogram*
## [5] str.logLik* str.POSIXt*
##
## Non-visible functions are asterisked
attach(staff)
# просмотр текущего окружения:
#рабочее пространство (".GlobalEnv")
#загруженные библиотеки(package:*)
#данные (staff)
search()
## [1] ".GlobalEnv" "staff" "package:stats"
## [4] "package:graphics" "package:grDevices" "package:utils"
## [7] "package:datasets" "package:methods" "Autoloads"
## [10] "package:base"