1 R-биометрия А. В. Коросов (http://www.petrsu.ru/People/korosov

advertisement
R-биометрия
А. В. Коросов (http://www.petrsu.ru/People/korosov/index.html)
стр.
1
1
2
6
8
13
13
15
19
Содержание
Введение
Про синтаксис
Ввод данных в массив
Статистические параметры
Анализ зависимостей
Скрипт (для регрессионного анализа)
Компонентный анализ
Сравнение выборок
Литература
Введение
нужен тем, кто хочет обрабатывать данные максимально быстро и полно.
В 3000 пакетах (packages) R реализованы практически все мыслимые процедуры количественной обработки в том числе биологических и экологических данных (R Core Team,
2012.). А то, чего нет, легко сделать самому.
Введение написано для того, чтобы читатель проникся чарующим духом R.
Выполнив и обдумав предложенные примеры, в R сможет работать любой.
Файл установки есть на сайте http://cran.gis-lab.info/. Запуск программы R –
двойной клик на иконке. Выход из программы – q() или Файл / Выйти. Для справки (En)
надо ввести ?команда. (см. ?help ).
Про синтаксис
Программа R – это интерпретатор, который выполняет команды, вводимые с клавиатуры (или из файла). После запуска программы R появляется стандартное приглашение >, после которого в этой же строчке следует ввести команду, затем нажать Enter.
«Язык» R ориентирован на обработку векторов (одномерных массивов) – наборов
ячеек памяти, в которых хранятся значения. Это значит, что процедуры перебора значений встроены в команды обращения к данным и осуществляются «по умолчанию».
Следствием этого является чрезвычайная простота написания команд R, выполняющих
очень сложные расчеты.
Чтобы различать данные, массивам даются имена (распознаются регистр, символы
точки, подчеркивания…). Для внесения данных в массив приняты знаки <-, ->, =. Организовать массив можно, в первую очередь, командой с() (от concatenation – сцепление),
которая сцепляет в массив перечисленные значения (есть и много других вариантов).
> x = c(1,2,4,6)
Для просмотра на экране содержимого массива следует просто набрать его имя. В
квадратных скобках будет указан номер первого выводимого элемента.
> x
[1] 1 2 4 6
Структура вывода будет определяться структурой данных, но ее можно отрегулировать, использовав команду print(), в которой нужно указать минимальное число значащих цифр. Через точку с запятой можно ввести несколько команд.
2
> x = c(1,2.45673,4,6); x
[1] 1.00000 2.45673 4.00000
> print(x,2)
[1] 1.0 2.5 4.0 6.0
6.00000
Используя внешние скобки можно увидеть результат выполнения команд (здесь в
старый массив добавили новые элементы).
> (x = c(x,5,78))
[1] 1.00000 2.45673 4.00000 6.00000
5.00000 78.00000
Для обращения к отдельной ячейке массива нужно указать ее номер в квадратных
скобках. Номер элемента можно хранить в отдельной ячейке и вызывать нужное значение
с помощью косвенной ссылки.
> x[3] = 3.456
> a = 5 ; x[a] = 4560 ; x
[1]
1.00000
2.45673
3.45600
6.00000 4560.00000
78.00000
Обратиться к нескольким ячейкам можно с помощью двоеточия (в примере создан новый массив из трех элементов старого).
> x2 = x[1:3]; x2
[1] 1.00000 2.45673 4.00000
Математические операции и функции (*, /, +, –, ^, sin, log) выполняются относительно всех элементов указанного массива. Вернуться к ранее введенным
командам можно с помощью стрелок  и  клавиатуры. Исправив ошибки или изменив
набор команду, можно вновь ее выполнить.
> sqrt(x[2]) ; x2^2; abs(-3);log2(x[3]);print(x2/*3,2)
[1] 1.567396
[1] 1.000000 6.035522 16.000000
[1] 3
[1] 2
Ошибка: неожиданный '*' в "print(x2/*"
> print(x2/3,2)
[1] 0.33 0.82 1.33
Ввод данных в массив
Для работы с массивами данных их следует подготовить во внешней программе,
например, в Excel’е. В исходной базе данных одной особи соответствует один ряд (row),
одному признаку – колонка (column). В примере взята база данных по мелким млекопитающим с такими признаками, как вид (spic), год (year), масса тела (w) и др.
Из Excel файл с данными следует экспортировать в текстовый формат *.csv.
Такой файл можно посмотреть и даже отредактировать в Блокноте среды Windows.
3
Для дальнейшего анализа представленный ниже массив следует целиком скопировать на лист Excel (через буфер обмена), сохранить с расширением *.csv и использовать в качестве примера для выполнения приведенных расчетов.
num,spic,mon,year,sex,fer,line,w,lt,lc,lp
3121,sar,8,2006,F,sad,2,12.1,71,34,12
3120,clg,8,2006,M,sad,2,18.7,84,41,17
3119,sar,8,2006,M,juv,3,6.6,61,44,12
3118,clg,8,2006,M,ad,3,19.9,83,37,16
3117,mag,8,2006,F,juv,1,13.5,86,18,16
3116,sar,8,2006,F,juv,1,6.9,56,38,12
3122,sar,8,2006,F,juv,2,6,63,36,9
3123,smi,8,2006,F,juv,2,2.9,46,38,10
3124,sar,8,2006,M,juv,2,6.5,62,38,12
3125,clg,8,2006,F,ad,2,23.7,87,35,16
3126,sar,8,2006,F,juv,2,6.5,66,34,11
3127,sar,8,2006,F,juv,32,7.6,68,43,10
3128,sar,8,2006,M,juv,134,,,,
3129,mag,8,2006,M,juv,55,11.1,61,16,16
3130,sar,8,2006,M,juv,134,7.4,68,36,9
3131,nfo,8,2006,M,juv,13,15.5,82,65,21
3132,sar,8,2006,F,juv,134,6.8,66,33,9
3133,clg,8,2006,M,juv,134,13.2,86,34,17
3134,sar,8,2006,F,juv,134,7.2,66,35,13
3135,sar,8,2006,F,juv,134,6.7,55,36,14
3136,clg,8,2006,F,sad,13,20.5,95,46,11
3137,smi,8,2006,M,juv,14,4,54,31,8
3138,sar,8,2006,M,juv,134,6.7,69,41,10
3114,clg,8,2006,M,juv,134,12.7,83,34,16
3115,clg,8,2006,,sad,54,18.6,89,38,14
3045,sbe,7,2006,F,,1,12,66,91,16
3046,sbe,7,2006,F,ad,2,14,60,87,18
3047,clg,7,2006,F,ad,2,25.3,90,45,16
3048,clg,7,2006,M,,2,26.1,95,50,17
3049,sar,7,2006,M,ad,2,12.2,68,45,12
3050,sar,7,2006,M,juv,2,7.8,62,43,10
Прежде чем открыть файл с данными, сначала командой setwd() нужно указать
среде R, с какой папкой (рабочей директорией, work directory) предстоит работать (в
примере c:/r/micro_mammals_goms), посмотреть название (getwd()) текущей папки и ее
содержимое (dir()).
> setwd('c:/r/micro_mammal_goms')
> getwd()
[1] "c:/r/micro_mammal_goms"
> dir()
[1] "legend.csv"
"mamm.csv"
"mamm.xls"
[5] "mlecopit.xls"
"mlecopit.csv"
Прочесть файл с данными в среду R можно с помощью команды read.csv().
Каждая команда в R имеет скобки, в которых записываются разнообразные аргументы.
По умолчанию считается, что файл с данными содержит заголовки названий (header =
TRUE), значения признаков разделены запятыми (sep = ’,’), целая и дробная часть разделены точкой (dec = ’.’); эти предположения делают команду крайне простой. Указанные в командах текстовые константы обязательно нужно заключать в кавычки
"…" или апострофы ’…’.
4
> (ml = read.csv("mamm.csv"))
num spic mon year sex fer line
w lt lc lp
1 3121 sar
8 2006
F sad
2 12.1 71 34 12
2 3120 clg
8 2006
M sad
2 18.7 84 41 17
3 3119 sar
8 2006
M juv
3 6.6 61 44 12
4 3118 clg
8 2006
M ad
3 19.9 83 37 16
5 3117 mag
8 2006
F juv
1 13.5 86 18 16
6 3116 sar
8 2006
F juv
1 6.9 56 38 12
7 3122 sar
8 2006
F juv
2 6.0 63 36 9
8 3123 smi
8 2006
F juv
2 2.9 46 38 10
9 3124 sar
8 2006
M juv
2 6.5 62 38 12
10 3125 clg
8 2006
F ad
2 23.7 87 35 16
11 3126 sar
8 2006
F juv
2 6.5 66 34 11
12 3127 sar
8 2006
F juv
32 7.6 68 43 10
13 3128 sar
8 2006
M juv 134
NA NA NA NA
14 3129 mag
8 2006
M juv
55 11.1 61 16 16
15 3130 sar
8 2006
M juv 134 7.4 68 36 9
16 3131 nfo
8 2006
M juv
13 15.5 82 65 21
17 3132 sar
8 2006
F juv 134 6.8 66 33 9
18 3133 clg
8 2006
M juv 134 13.2 86 34 17
19 3134 sar
8 2006
F juv 134 7.2 66 35 13
20 3135 sar
8 2006
F juv 134 6.7 55 36 14
21 3136 clg
8 2006
F sad
13 20.5 95 46 11
22 3137 smi
8 2006
M juv
14 4.0 54 31 8
23 3138 sar
8 2006
M juv 134 6.7 69 41 10
24 3114 clg
8 2006
M juv 134 12.7 83 34 16
25 3115 clg
8 2006
sad
54 18.6 89 38 14
26 3045 sbe
7 2006
F
1 12.0 66 91 16
27 3046 sbe
7 2006
F ad
2 14.0 60 87 18
28 3047 clg
7 2006
F ad
2 25.3 90 45 16
29 3048 clg
7 2006
M
2 26.1 95 50 17
30 3049 sar
7 2006
M ad
2 12.2 68 45 12
31 3050 sar
7 2006
M juv
2 7.8 62 43 10
При чтении данных из файла R формирует двумерный массив, данные в котором
организованы в таблицу, состоящую из рядов (rows) и колонок (columns). Позиция отдельной ячейки в этом массиве указывается в квадратных скобках: на первом месте
должен стоять номер ряда, на втором через запятую – номер столбца. С помощью
двоеточия можно указать на несколько смежных ячеек.
> ml[1:5,3:7]
mon year sex
1
8 2006
F
2
8 2006
M
3
8 2006
M
4
8 2006
M
5
8 2006
F
fer line
sad
2
sad
2
juv
3
ad
3
juv
1
Обратиться к выборочным рядам или колонкам можно с помощью команды
c(), которая сцепляет набор несмежных номеров в один блок.
> pr = c(2,4,9)
> ml[c(5,25,27),pr]
spic year lt
5
mag 2006 86
25 clg 2006 89
27 sbe 2006 60
Чтобы обратиться ко всем значениям ряда или колонки в квадратных скобках на
нужном месте следует оставить пробел, но обязательно надо ставить запятую.
> ml[,3]
[1] 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 7 7 7 7 7 7
> ml[3,]
num spic mon year sex fer line
w lt lc lp
3 3119 sar
8 2006
M juv
3 6.6 61 44 12
5
R ориентирован на обработку векторов; даже двумерный массив выступает как
множество одномерных массивов (колонок), приставленных друг к другу. К данным в отдельной колонке можно обратиться по номеру или по имени и выполнять операции отдельно от других колонок. Имя должно быть составлено из имени массива и имени колонки с использованием знака доллара $.
> ml$w[1:5]
[1] 12.1 18.7
6.6 19.9 13.5
Первый этап обработки– контроль за качеством данных. Сначала стоит их отсортировать и оценить экстремальные значения.
> sort(ml$lc)
[1] 16 18 31 33 34 34 34 34 35 35 36 36 36 37 38 38 38 38 39 41 41 43 43 44
[25] 45 45 46 50 65 87 91
Вызывают подозрение две особи с очень длинными хвостами (lc: 87 и 91 мм). Из
массива данных извлекаем ряды (поэтому условие ставим на первое место до запятой), в которых значение длины хвоста (ml$lc) превышает 80. Оказалось, что это две лесные мышовки (sbe), для которых такие пропорции – норма.
> ml[ml$lc>80,]
num spic mon year sex fer line w lt lc lp
26 3045 sbe
7 2006
F
1 12 66 91 16
27 3046 sbe
7 2006
F ad
2 14 60 87 18
Для предварительной оценки разброса данных можно воспользоваться функциями
обобщения данных. Для числовых данных удобно строить «стебель с листьями». Поскольку по умолчанию принят шаг 2, строчка содержит десятые, относящиеся к двум числам стебля (например, 12 | 012725 включает значения от 12.0 до 12.7, а также 13.2, 13.5).
> stem(ml$w)
The decimal point is at the |
2 | 9
4 | 0
6 | 055677892468
8 |
10 | 1
12 | 012725
14 | 05
16 |
18 | 679
20 | 5
22 | 7
24 | 3
26 | 1
Можно также нарисовать гистограмму распределения переменной, в списке аргументов указав подписи осей (регулируются цвет, размер и др. атрибуты, см. ?hist).
> hist(ml$w,main="Проверка массы",ylab='Чатота, экз.',xlab=
'Масса, г')
6
> ta = table(ml$sex); ta
> plot(ta)
F M
1 15 15
a
ta
Категориальные данные (качественные, текстовые) удобнее обобщать с помощью функции table(), а представлять в форме
15
диаграммы. Оказалось, что у одной особи пол не
внесен в базу, значит, требуется проверка по жур10
налу.
5
0
F
M
Статистические параметры
Если данные оказались валидными, можно приступать к статистической обработке. С помощью специальных функций рассчитаем основные статистические параметры:
объем выборки (длину массива, или число рядов), среднюю, стандартное отклонение для
отдельной колонки. В примере подсчитана длина вектора ml$w, которая и есть высота таблицы ml. Средняя и дисперсия показали пустое число, поскольку в таблице были пробелы
(особь с num 3128).
> length(ml$w);nrow(ml);mean(ml$w);sd(ml$w)
[1] 31
[1] 31
[1] NA
[1] NA
Чтобы не учитывать пробелы в данных, в атрибуты команд вводятся условие исключения пропуском na.rm = T (NA remove = TRUE: правда, что нужно удалять пробелы).
> mean(ml$w,na.rm = T); sw = sd(ml$w,na.rm = T)
[1] 11.95667
> sw
[1] 6.485617
Эффективнее считать и выводить на экран или в массив расчеты для двух или для
всех переменных сразу. Команда data.frame объединяет два вектора (столбца) в двумерный массив, для которого и выполняется действие.
> colMeans(data.frame(ml[,8],ml$lt),na.rm = T)
ml...8.
ml.lt
11.95667 71.60000
> colMeans(ml[,8:11],na.rm = T)
w
lt
lc
lp
11.95667 71.60000 41.40000 13.33333
Еще более эффективно вывести сразу несколько статистических параметров
(границы, квантили, медиана, средняя, наличие пропусков) для всей таблицы. Расчет
можно записать в текстовый массив.
> ss = summary(ml[8:11]); ss
w
lt
Min.
: 2.900
Min.
:46.00
1st Qu.: 6.725
1st Qu.:62.00
Median :11.550
Median :68.00
Mean
:11.957
Mean
:71.60
3rd Qu.:15.125
3rd Qu.:83.75
Max.
:26.100
Max.
:95.00
NA's
:1
NA's
:1
> ss[4,2]
[1] "Mean
:71.60 "
lc
Min.
:16.00
1st Qu.:34.25
Median :38.00
Mean
:41.40
3rd Qu.:43.75
Max.
:91.00
NA's
:1
lp
Min.
: 8.00
1st Qu.:10.25
Median :12.50
Mean
:13.33
3rd Qu.:16.00
Max.
:21.00
NA's
:1
С биологической точки зрения странно считать общую статистику для животных
разных видов. Важно выполнять расчет статистики отдельно для каждой категории
7
данных. В примере выполнена общая оценка статистических параметров для переменной
масса тела (ml$w) – раздельно для каждого вида (на признак классификации, ml$spic, указывает второй аргумент, его название INDEX = можно опустить).
> (ss =
$clg
Min.
12.70
$mag
Min.
11.1
$nfo
Min.
15.5
$sar
Min.
6.000
$sbe
Min.
12.0
$smi
Min.
2.900
tapply(ml$w,INDEX = ml$spic,summary))
1st Qu.
18.60
Median
19.90
Mean 3rd Qu.
19.86
23.70
Max.
26.10
1st Qu.
11.7
Median
12.3
Mean 3rd Qu.
12.3
12.9
Max.
13.5
1st Qu.
15.5
Median
15.5
Mean 3rd Qu.
15.5
15.5
Max.
15.5
1st Qu.
6.625
Median
6.850
Mean 3rd Qu.
7.643
7.550
Max.
12.200
1st Qu.
12.5
Median
13.0
Mean 3rd Qu.
13.0
13.5
Max.
14.0
1st Qu.
3.175
Median
3.450
Mean 3rd Qu.
3.450
3.725
Max.
4.000
NA's
1
Результаты можно записать в массив (автоматически задается тип list, список).
Выяснить тип массива можно командой is. В списке данные разного качества разделены
на блоки; обращаться к данным списка можно как к блокам, так и как к отдельным значениям.
> is.factor(ss)
[1] FALSE
> is.list(ss)
[1] TRUE
> ss$nfo
Min. 1st Qu. Median
15.5
15.5
15.5
> ss[3]
$nfo
Min. 1st Qu. Median
15.5
15.5
15.5
> ss$nfo[4]; ss$nfo[4]/2
Mean
15.5
Mean
7.75
Mean 3rd Qu.
15.5
15.5
Max.
15.5
Mean 3rd Qu.
15.5
15.5
Max.
15.5
Расчет стандартного отклонения можно организовать аналогично. Однако для этого в выборке должно быть, как минимум, два значения, иначе получим значение NA.
> print(tapply(ml$w,ml$spic,sd,na.rm = T),1)
clg mag nfo sar sbe smi
4.8 1.7 NA 2.0 1.4 0.8
Для обработки данных по каждому виду отдельно, возможно, лучше организовать
из них отдельный массив. Сначала следует выбрать особей одного вида, например, темную полевку, M. agrestis, mag (в приведенном массиве данных особям соответствуют ряды). Условие соответствия (равенства) задается знаком == . Команда на проверку соответствия значений – условию может быть записана двумя способами. В команде
ml$spic == 'mag' указано имя столбца со значениями вида. В команде ml[,2]=='mag'
указан номер колонки 2, в котором и приведены обозначения видов. Результатом выполнения обеих команд оказывается набор значений TRUE, если условие выполнено, и FALSE в
противоположном случае (значок диеза # показывает R, что идущие за значком символы
есть неисполняемые комментарии, который R игнорирует).
> ml$spic=='mag' # или ml[,2]=='mag'
8
[1] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[13] FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE
Чтобы из общей таблицы выбрать серию рядов с данными, соответствующими
заданному условию, нужно это условие включить в квадратные скобки, причем на первое
место, обозначающее именно номера рядов. На второе место в квадратных скобках ставим
номер колонки с интересующими нас данными. Чтобы узнать номера темных полевок,
указываем первую колонку. Если же нас интересуют все данные, то при вызове результатов на втором месте, после запятой, ничего не ставить не нужно.
> ml[ml[,2]=='mag',1]
[1] 3117 3129
> ml[ml[,2]=='mag',]
num spic mon year sex fer line
w lt lc lp
5 3117 mag
8 2006
F juv
1 13.5 86 18 16
14 3129 mag
8 2006
M juv
55 11.1 61 16 16
Вообще говоря, результаты сравнения значений с условиями (массив величин
можно сохранить в отдельном векторе, который и указать в выводе результатов. Причем вызывать можно не все данные, а только нужные для расчетов (столбцы с численными значениями 8, 9, 10, 11).
TRUE / FALSE)
> rmag = ml[,2]=='mag'
> cnum = c(8,9,10,11)
> (nmag = ml[rmag,cnum])
w lt lc lp
5 13.5 86 18 16
14 11.1 61 16 16
Теперь можно рассчитать полную статистику для данного вида. Команда apply
позволяет выполнять действия по отдельности для каждого столбца или ряда таблицы.
В примере атрибут 2 означает, что указанные статистические функции (summary, sd)
должны применяться к объектам, обозначенным второй позицией в указанным массиве
(nmag), т. е. к столбцам. Если бы стояло значение 1, расчет выполнялся бы для рядов. Значения 3 и больше имеют смысл только для многомерных массивов.
> (m.st = apply(nmag,2,summary))
w
lt
lc lp
Min.
11.1 61.00 16.0 16
1st Qu. 11.7 67.25 16.5 16
Median 12.3 73.50 17.0 16
Mean
12.3 73.50 17.0 16
3rd Qu. 12.9 79.75 17.5 16
Max.
13.5 86.00 18.0 16
> m.sd = apply(nmag,2,sd);print(m.sd,2)
w
lt
lc
lp
1.7 17.7 1.4 0.0
> m.med = apply(nmag,2,median);print(m.med,4)
w
lt
lc
lp
12.3 73.5 17.0 16.0
Анализ зависимостей
Группа методов, изучающих зависимости между признаками требует создания отдельной выборки (массива) для отдельного вида. Для примера выберем рыжую полевку.
> clg = ml[ml[,2]=='clg',]
num spic mon year sex fer line
w lt lc lp
2 3120 clg
8 2006
M sad
2 18.7 84 41 17
4 3118 clg
8 2006
M ad
3 19.9 83 37 16
10 3125 clg
8 2006
F ad
2 23.7 87 35 16
18 3133 clg
8 2006
M juv 134 13.2 86 34 17
21 3136 clg
8 2006
F sad
13 20.5 95 46 11
24 3114 clg
8 2006
M juv 134 12.7 83 34 16
25 3115 clg
8 2006
sad
54 18.6 89 38 14
28 3047 clg
7 2006
F ad
2 25.3 90 45 16
29 3048 clg
7 2006
M
2 26.1 95 50 17
9
Выполнять первичный анализ зависимостей между количественными признаками (переменными) лучше всего визуально – с помощью графических средств R. Для
этой цели можно использовать общую команду построения точечных диаграмм plot() и
специальную команду matplot(). Каждая из них имеет богатые возможности для формирования наиболее наглядного представления данных (подписи осей, цвета и характер расположения элементов), которые мы опустим, рассмотрев только важнейшие структурные
характеристики.
Функция plot() соответствует «точечной диаграмме» пакета Excel. Ось абсцисс
отводится одной переменной, ось ординат – другой. Кроме заголовка (main) и подписи
осей (xlab, ylab) в число атрибутов можно включить тип отображаемого объекта type
('p' – символ, 'l' – линия, 'b' – и символ, и линия, и др.); по умолчанию type='p'. Если
type='l' или type='b', то можно изменить такие атрибуты линии, как тип линии lty (1
– сплошная, 2 – пунктирная…), толщина линии lwd (1 пиксель, 2 пикселя….) и другие
(см. ?plot). Отметим, что в примерах использованы разные способы обращения к данным.
>
>
>
>
>
plot(clg$w,clg$lt, ylab='Масса тела, г',xlab='Длина тела, мм')
plot(clg$w,clg[,9], type='p', ylab='Масса тела, г',xlab='Длина тела, мм')
plot(clg$w,clg$lt,type='l', lty = 1, lwd = 3)
plot(clg[,9:10],type='b', lty = 3, lwd = 1)
plot(clg[,c(8,10)],type='b', lty = 3, lwd = 1)
Функция matplot(x,y,…) многофункциональна. Если в первой (x) и второй (y)
позициях указаны массивы или векторы, создается «точечная диаграмма», причем, для
нескольких рядов (по умолчанию type='p', вместо пиктограмм появляются номера рядов,
тип значка задается аргументом pch …). Если же в позиции (x) указан лишь один массив (с
несколькими полями), то создается аналог «графика» пакета Excel – по ось абсцисс отложении номера объектов в изучаемом массиве, по оси ординат – значений переменных.
> matplot(clg[,8],clg[,c(9,11)],xlab='Масса',ylab='Длина хвоста 1 и стопы 2')
> matplot(clg[,c(8,9,11)],xlab='номер',ylab='1-стопа 2-хвост 3-масса')
> matplot(clg[,8:10],xlab='номер',type='l')
Диаграммы типа «график» смотрятся лучше, если упорядочить объекты в порядке
возрастания значений какого-либо признака, например, по длине тела. Упорядочивание
очень важно для корректного отображения доверительных интервалов для линии регрессии (см. ниже). Сортировка отдельной переменной выполняется командой sort(), а упорядочивание всех рядов массива относительно одной переменной – командой order().
После этого график выглядит много лучше, указывая на нюансы варьирования изучаемых
признаков на фоне монотонного возрастания реперного признака.
> clg;clg = clg[order(clg$lt),];clg
10
num spic mon year sex fer line
w lt lc lp
3120 clg
8 2006
M sad
2 18.7 84 41 17
3118 clg
8 2006
M ad
3 19.9 83 37 16
3125 clg
8 2006
F ad
2 23.7 87 35 16
3133 clg
8 2006
M juv 134 13.2 86 34 17
3136 clg
8 2006
F sad
13 20.5 95 46 11
3114 clg
8 2006
M juv 134 12.7 83 34 16
3115 clg
8 2006
sad
54 18.6 89 38 14
3047 clg
7 2006
F ad
2 25.3 90 45 16
3048 clg
7 2006
M
2 26.1 95 50 17
num spic mon year sex fer line
w lt lc lp
4 3118 clg
8 2006
M ad
3 19.9 83 37 16
24 3114 clg
8 2006
M juv 134 12.7 83 34 16
2 3120 clg
8 2006
M sad
2 18.7 84 41 17
18 3133 clg
8 2006
M juv 134 13.2 86 34 17
10 3125 clg
8 2006
F ad
2 23.7 87 35 16
25 3115 clg
8 2006
sad
54 18.6 89 38 14
28 3047 clg
7 2006
F ad
2 25.3 90 45 16
21 3136 clg
8 2006
F sad
13 20.5 95 46 11
29 3048 clg
7 2006
M
2 26.1 95 50 17
> matplot(clg[,c(8,10,11)], type='b',col = 4,lty = 2,lwd = 2, pch=1)
> matplot(clg[,c(8,10,9)], type='b',lty = 3,lwd = 2)
2
4
10
18
21
24
25
28
29
Используя функцию matplot() можно объединить две точечные диаграммы. Для этого сначала отбираем массивы по полу, потом рисуем две точечные диаграммы, используя разные пиктограммы (кружки pch=1 и
точки pch=16). Для отображения всех точек в аргументах
первого графика указываем пределы значений по оси абсцисс xlim=c(80,100) и по оси ординат ylim=c(30,50).
> cm = clg[clg$sex=='M',];cf = clg[clg$sex=='F',]
> matplot(cf[,9],cf[,10],pch=16,xlim=c(80,100),ylim=c(30,50))
> matplot(cm[,9],cm[,10],pch=1,add=T)
Вернемся к статистическим расчетам. Корреляционный анализ (cor()) выполняет расчет коэффициента корреляции (по умолчанию – Пирсона) и его значимости (достоверности отличия от нуля). Атрибут use разрешает не учитывать пропуски (NA) в данных.
Уместно использовать и метод Спирмена. В примере оба коэффициента корреляции между изученными признаками (длина тела и хвоста) оказались значимыми (p-value < 0.05).
Для интерпретации уровней корреляции между разных признаков удобна диаграмма парных зависимостей pairs(). С помощью этой же команды можно получить полную матрицу корреляций между всеми переменными одного массива (исключая пропуски).
> cor(clg$lc, clg$lt, use = 'na.or.complete')
[1] 0.8182027
> cor(clg$lc, clg$lt,method = "spearman")
[1] 0.7721588
> cor.test(clg$lc, clg$lt,method = "pearson")
Pearson's product-moment correlation
data: clg$lc and clg$lt
t = 3.7653, df = 7, p-value = 0.007026
alternative hypothesis: true correlation is
equal to 0
95 percent confidence interval:
0.3374428 0.9604365
sample estimates:
not
11
cor
0.8182027
> cor.test(clg$lc, clg$lt,method = "spearman")
Spearman's rank correlation rho
data: clg$lc and clg$lt
S = 27.3409, p-value = 0.01475
alternative hypothesis: true rho is not equal to 0
sample estimates:
rho
0.7721588
> pairs(ml[ml[,2]=='sar',8:10],main='Пропорции')
> print(cor(ml[,8:11], use = 'na.or.complete'),2)
w
lt
lc
lp
w 1.00 0.870 0.186 0.66
lt 0.87 1.000 -0.013 0.53
lc 0.19 -0.013 1.000 0.34
lp 0.66 0.527 0.342 1.00
Для того чтобы выполнить линейный регрессионный анализ зависимости (~) количественной переменной y от количественной переменной x служит команда lm(y~x).
Для примера возьмем массу w и длину тела lt для рыжей полевки (clg). Первым результатом являются коэффициенты регрессии в модели w = 0.6178*lt–34.5123.
> clg.wlt = lm(clg$w~clg$lt))
Call:
lm(formula = clg$w ~ clg$lt)
Coefficients:
(Intercept)
clg$lt
-34.5123
0.6178
Используя уравнение, нетрудно рассчитать модельные значения массы тела mw и сравнить их с реальными clg$w. Диаграмма показывает, что строгой зависимости между исходными переменными нет.
Об этом же говорит и невысокий коэффициент корреляции.
> mw = 0.6178*clg$lt-34.5123
> print(mw,3)
[1] 17.4 16.8 19.2 18.6 24.2 16.8 20.5 21.1 24.2
> print(clg$w,3)
[1] 18.7 19.9 23.7 13.2 20.5 12.7 18.6 25.3 26.1
> plot(clg$w,mw)
> cor(clg$w,clg$lt)
[1] 0.6036835
Оценки значимости коэффициентов регрессии дает команда summary. Оба коэффициента регрессии оказались незначимыми по критерию Стьюдента: Pr(>|t|)> 0.05.
> summary(clg.wlt)
Call:
lm(formula = clg$w ~ clg$lt)
Residuals:
Min
1Q Median
3Q
Max
-5.420 -3.680 1.316 3.134 4.462
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -34.5123
27.1710 -1.270
0.2446
clg$lt
0.6178
0.3084
2.003
0.0852 .
--Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 4.068 on 7 degrees of freedom
Multiple R-squared: 0.3644,
Adjusted R-squared: 0.2736
F-statistic: 4.014 on 1 and 7 DF, p-value: 0.08519
Дисперсионный анализ также показал, что модель не адекватна данным по критерию Фишера: Pr(>F)> 0.05.
> anova(clg.wlt)
Analysis of Variance Table
Response: clg$w
12
Df Sum Sq Mean Sq F value Pr(>F)
clg$lt
1 66.415 66.415 4.0138 0.08519 .
Residuals 7 115.827 16.547
--Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Для модели зависимости хвоста от длины тела дисперсионный анализ показал ее
адекватность данным по критерию Фишера: Pr(>F)< 0.01. В этом случае есть смысл построить зоны вероятного присутствия линии регрессии.
> cor(clg$lc,clg$lt)
[1] 0.8182027
> anova(lm(clg$lc~clg$lt))
Analysis of Variance Table
Response: clg$lc
Df Sum Sq Mean Sq F value
Pr(>F)
clg$lt
1 182.092 182.092 14.177 0.007026 **
Residuals 7 89.908 12.844
--Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Прогнозные значения линии регрессии и ее доверительный интервал (confi(доверительная зона) рассчитываются с помощью функции predict(). В
число ее важных аргументов входит массив с результатами lm-регрессионного анализа (в
примере clg.ltlc), а также массив типа «таблица» (data.frame), содержащая значения
независимой переменной, использованной в регрессионном анализе (x) и указание на то,
какой интервал требуется рассчитать (в примере- доверительный, interval = "confidence). Поскольку в анализе участвовал числовой вектор столбец clg[,9] (или lcg$lt),
его необходимо предварительно преобразовать в таблицу командой data.frame(). Доверительную зону лучше всего рисовать на фоне исходных данных (команда plot). При построении диаграммы зависимости прогнозных значений от независимой переменной в
списке аргументов команды matplot() указываем источники данных (x,clg.pc), тип
отображения (type='l', линия), три типа линии (регрессия – сплошная, границы зоны –
пунктирные), линии синего цвета (col=4), указание на то, что эта диаграмма добавляется к
ранее нарисованной (add=TRUE). Обращаем внимание читателя на то, что красивой картинка буте только, если предварительно упорядочить значения анализируемого массива (у
нас clg) в порядке увеличения независимой переменной (у нас lt) с помощью команды
order() (см. выше). На распечатке fit – регрессия, lwr, upr – нижний и верхний ряды
(границы) доверительной зоны.
dence interval)
>
>
>
>
>
1
2
3
4
5
6
7
8
9
x = data.frame(clg[,9])
clg.pc <- predict(clg.ltlc,x,interval="confidence")
plot(clg[,9:10],xlab='длина тела, мм',ylab='длина хвоста, мм')
matplot(x,clg.pc,type='l',lty=c(1,2,2), col=4, add=T)
print(clg.pc,3)
fit lwr upr
34.9 30.6 39.2
34.9 30.6 39.2
35.9 32.1 39.7
38.0 34.9 41.1
39.0 36.1 41.9
41.0 38.1 43.9
42.0 38.9 45.1
47.2 41.9 52.5
47.2 41.9 52.5
13
Скрипт для регрессионного анализа
Ценность полученной картинки для научной публикации довольно велика, однако
для ее построения было выполнено несколько команд. При обработке следующего набора
данных было бы удобно обратить сразу к необходимому комплексу команд, дающих
единственный конечный результат. В среде R можно сохранить такой набор в одном файле, который называется скрипт. Его можно открыть, отредактировать, запустить на решение целиком, блоками или отдельными командами. Для создания файла скрипта в среде R
следует дать команду главного меню Файл / Новый скрипт и по очереди скопировать в открывшееся окно команды, правильно выполненные ранее. Слишком длинные команды
можно перенести на следующую строку. Чтобы не забыть назначения команд после них
можно ввести значок диеза # и комментарии. Сохраняется скрипт командой главного меню: Файл / Сохранить. Для запуска скрипта дать команду меню Правка / Запустить все.
Для запуска отдельной или блока команд выделить их мышкой и дать команду меню
Правка / Запустить строку или блок (Ctrl+R). Если нас интересуют другие признаки, меняем их в скрипте, сохраняем его с новым именем, запускам на решение. В примере заменили вид clg на sar (причем с помощью команды меню Правка / Замена). Можно заметить,
что для бурозубок зависимость между длиной хвоста и тела отсутствует.
Компонентный анализ
Один из вариантов проведения компонентного (см. Коросов, 1996; Коросов, 2007)
состоит в выполнении серии команд, представленных ниже в скрипте. В расчетах участвуют числовые переменные w, lt, lc, lp. Скрипт лучше запускать пошагово (Ctrl+R).
mm = na.omit(ml)
# ликвидируем пропуски в данных
dd = scale(mm[,8:11])
# нормирование данных
(mm.pca = princomp(dd))
# расчет дисперсий (собственных значений)
(mm.l = loadings(mm.pca)) # факторные нагрузки (собственные векторы)
mm.p = predict(mm.pca)
# расчет значений компонент
print(mm.p[1:5,],2)
# вывод значений компонент для 5 объектов
biplot(mm.pca, xlab='первая компонента')
# рисуем биплот
plot(mm.p[,1:2])
# ординация объектов в осях 1 и 2 компонент
plot(mm.p[,1:2], type="n", xlab="PC1", ylab="PC2") # затираем пиктограммы
text(mm.p[,1:2], labels=mm[,2])
# выводим метки объектов
Поскольку 17-й объект содержит значения NA, его следует удалить.
> mm = na.omit(ml)
# ликвидируем пропуски в данных
Расчет нормированных значений для каждой колонки выполняется по формуле
t = (x – M) / S (M и S – средняя и стандартное отклонение, x – значение признака для конкретной особи).
> dd = scale(mm[,8:11])
# нормирование данных
Первичные расчеты выводятся в отдельный массив, который участвует в дальнейших расчетах. Пока же выводятся только значения стандартных отклонений всех компонент, из которых видно, что первые компоненты превышают единицу, т. е. могут считаться значимыми.
> (mm.pca = princomp(dd))
Call:
princomp(x = dd)
# расчет дисперсий (собственных значений)
14
Standard deviations:
Comp.1
Comp.2
Comp.3
Comp.4
1.5353226 1.0122029 0.6213572 0.3143433
4 variables and 30 observations.
Команда loadings()загружает в массив mm.l
факторные нагрузки в виде собственных векторов. Вариант нормирования их значений представлен ниже. Под матрицей
нагрузок представлена матрица весовых коэффициентов, которые по умолчанию были
приняты равными. Факторные нагрузки показывают, что первая компонента уловила изменчивость в основном по массе, длине тела и стопы, вторая компонента – по длине хвоста.
> (mm.l =
Loadings:
Comp.1
w -0.606
lt -0.559
lc -0.199
lp -0.530
loadings(mm.pca)) # факторные нагрузки (собственные векторы)
Comp.2 Comp.3 Comp.4
0.147 -0.249 0.741
0.369 -0.358 -0.651
-0.891 -0.391 -0.119
-0.222 0.810 -0.117
Comp.1 Comp.2 Comp.3 Comp.4
SS loadings
1.00
1.00
1.00
1.00
Proportion Var
0.25
0.25
0.25
0.25
Cumulative Var
0.25
0.50
0.75
1.00
Используя команду predict(), можно вывести значения компонент.
> mm.p = predict(mm.pca)
# расчет значений компонент
> print(mm.p[1:5,],2)
Comp.1 Comp.2 Comp.3 Comp.4
1
0.32
0.50 -0.13 0.149
2 -1.73
0.27
0.31 0.041
3
1.12 -0.47
0.10 -0.069
4 -1.59
0.57
0.15 0.292
5 -0.87
1.59
0.79 -0.441
Взаимное расположение объектов лучше анализировать, когда на диаграмму выводятся маркеры объектов (в примере – вид особей). Биплот объединяет ординацию особей
и соотношения факторных нагрузок. Все виды хорошо разделились компонентам: от
обыкновенных бурозубок (некрупных со средним хвостом) наверх отходят молодые
короткохвостые темные полевки, влево крупные рыжие полевки, вниз – небольшие длиннохвостые мышовки, вправо – очень маленькие малые бурозубки.
>
>
>
>
plot(mm.p[,1:2])
# ординация объектов в осях 1 и 2 компонент
plot(mm.p[,1:2], type="n", xlab="PC1", ylab="PC2") # затираем пиктограммы
text(mm.p[,1:2], labels=mm[,2])
# выводим метки объектов
biplot(mm.pca, xlab='первая компонента')
# рисуем биплот
Результаты компонентного анализа можно получить с помощью команды расчета
собственных (eigen) значений и собственных векторов матрицы корреляций.
> print(eigen(cor(mm[,8:11])),2)
$values
[1] 2.4 1.1 0.4 0.1
$vectors
[,1] [,2] [,3] [,4]
[1,] 0.61 0.15 -0.25 0.74
[2,] 0.56 0.37 -0.36 -0.65
15
[3,] 0.20 -0.89 -0.39 -0.12
[4,] 0.53 -0.22 0.81 -0.12
Сравнение выборок
Для наглядного и статистического сравнения двух выборок сначала нужно их
сформировать (точка используется в названиях массивов для наглядности: clg.w – масса
w, рыжих полевок clg). Анализ показал, что с вероятностью p-value = 2.985e-05 средние арифметические 7.642857 и 19.855556 различаются достоверно. Оригинальная иллюстрация «ящик с усами» наглядно отображает это существенное различие.
>
>
>
>
sar.w = ml[ml[,2]=='sar',8]
clg.w = ml[ml[,2]=='clg',8]
boxplot(sar.w,clg.w,ylab = 'Масса, г',names = c('sar','clg'))
t.test(sar.w,clg.w)
Welch Two Sample t-test
data: sar.w and clg.w
t = -7.2883, df = 9.773, p-value = 2.985e-05
alternative hypothesis:
true difference in means is not equal to 0
95 percent confidence interval:
-15.958094 -8.467303
sample estimates:
mean of x mean of y
7.642857 19.855556
Если есть сомнения в том, что распределение признаков нормальное, следует применять непараметрические тесты, например, Уилкоксона. Различия между выборками
также достоверны.
> wilcox.test(sar.w,clg.w, na.rm = T)
Wilcoxon rank sum test with continuity correction
data: sar.w and clg.w
W = 0, p-value = 8.18e-05
alternative hypothesis: true location shift is not equal to 0
Дисперсионный анализ (сравнение средних арифметических нескольких выборок) требует определенной организации данных. Один из возможных вариантов составления градации состоит в том, чтобы некий качественный признак выступал в качестве индикатора градации фактора; некий другой, количественный, признак – в качестве анализируемого. Рассмотрим пару: изучаемый признак – длина тела (колонка ml$lt), индикатор – вид, (колонка ml$spic). Для общего заключения достаточно команды aov(), полную таблицу дисперсионного анализа выводит команда summary.aov. Различия факториальной и случайной дисперсий значимы, с уровнем значимости p<0.001 (Signif.) фактор
«вид» существенно влияет на размеры тела. В комментариях сказано, что одно наблюдение было удалено из-за отсутствия данных (особь 3128).
> (m.aov = aov(ml$lt~ml$spic))
Call:
aov(formula = ml$lt ~ ml$spic)
Terms:
ml$spic Residuals
Sum of Squares 4351.486
831.714
Deg. of Freedom
5
24
Residual standard error: 5.88683
Estimated effects may be unbalanced
1 observation deleted due to missingness
> summary.aov(m.aov)
Df Sum Sq Mean Sq F value
Pr(>F)
ml$spic
5
4351
870.3
25.11 8.31e-09 ***
Residuals
24
832
34.7
--Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
1 observation deleted due to missingness
16
Бутстреп (как вариант ресамплинга) все настойчивее стучится в двери биометрических исследований. Бутсреп отличается от параметрических и непараметрических критериев тем, что не требует никакой априорной теории и модели распределения каких бы
то ни было «стандартных» критериев. Он пользуется только «соглашением о 95%». В
каждом конкретном случае при сравнении двух совокупностей он строит свой критерий,
который может быть ориентирован как на сравнение параметров (как параметрический
критерий), так и на сравнение выборок в целом (как непараметрический критерий). Таким
показателем может быть стьюдентизированный размах (|M1-M2|/md), просто разность
между средними (M1-M2), различие между стандартными отклонениями (S1-S2) или отношение дисперсий (S1/S2), или мера различия по рангам (∑R1/∑R2), мера различия по
Съеренсену (1-2c/(a+b)) и пр.
Исследуем значимость различия двух исходных выборочных средних Кри = |Ми1–
Ми2|. Как и в большинстве случаев применения других критериев, нулевая гипотеза состоит в том, что различия между средними случайны (связаны с ошибкой репрезентативности) и оба значения оценивают одну и ту же генеральную среднюю (обе выборки взяты
из одной генеральной совокупности). Далее поступают следующим образом: условно
принимают, что две изучаемые выборки (объема n1 и n2) достаточно хорошо характеризуют генеральную совокупность, чтобы выступить ее моделью; их объединяют и рассматривают как генеральную совокупность. После этого начинают извлекать из этой условной
генеральной совокупности (объема n1 + n2) новые выборки (объемом n1 и n2), в которые с
равной вероятностью могут попасть любые выборочные значения из обеих исходных выборок. Для каждой пары новых смешанных выборок вычисляют вторичные средние Мв1
и Мв2 и находят их различие Крв = |Мв1–Мв2|. Эту процедуру выполняют несколько тысяч раз. Тем самым обобщенная выборка «размножается» (ре – повторение, сампл – образец), порождая практически безграничное множество вариант (что характерно для генеральной совокупности.) Многократное извлечение выборок дает многочисленную совокупность значений Крв, для которой строят гистограмму распределения. Далее для доверительной вероятности p = 0.95 вычисляют квантили распределения Крв0.025 и Крв0.0975.
(Внутренняя процедура рассчитывает кумуляту частот от 0 до 100% и отбирает по 2.5%
значений с обоих краев кумуляты.) Эти границы эмпирического распределения обозначают пределы варьирования величины Крв по случайным причинам (в силу ошибок репрезентативности). Области за этими границами соответствуют ситуациям, когда выборки
взяты из разных генеральных совокупностей. Теперь остается только сравнить исходное
значение Кри с полученными границами доверительной области. Если значение Кри выходит из диапазона от Крв0.025 до Крв0.975, значит, средние арифметические различаются
значимо, а исходные выборки взяты из разных генеральных совокупностей. Особо отметим, что для этого метода совершенно неважно, какой характер имеет распределение изучаемой случайной величины. Поскольку большинство биометрических переменных не
имеет нормального распределения, то этот метод применим всегда и в отношении любых
параметров или выборок.
Возникает, правда, вопрос, насколько правомочно считать объединение двух эмпирических выборок хорошим представителем генеральной совокупности? Аргументированный ответ на этот вопрос дает автор метода бутстрепа – свойства «размноженной»
выборки при росте числа повторностей асимптотически приближаются к свойствам генеральной совокупности, из которой выборки были взяты. Если «размножение» вариант исходных ограниченных выборок выполнено достаточно большое число раз (несколько тысяч), то полученное распределение различий между параметрами (Крв) будут почти точно
совпадать с распределением этого различия для выборок, полученных из исходной генеральной совокупности. В среде R задачи такого рода решаются в следующем порядке.
1. читаем файл с данными (формат *.csv),
2. вычисляем оценку различия между двумя исходными выборками Кри,
3. создаем и выполняем серию циклов ресамплинга и сбора статистики Крв,
17
4. строим гистограмму распределения переменной Крв,
5. определяем процентили распределения Крв и сравниваем их с Кри,
6. делаем статистический и биологический вывод по результатам сравнения.
В примере анализировалась (см. скрипт) достоверность различия между средней
длиной хвоста рыжих полевок (clg) и обыкновенных бурозубок (sar).
setwd('c:/r/micro_mammal_goms')
ml = read.csv("mamm.csv")
mm = na.omit(ml)
lc = mm[mm$spic=='clg',10] ; ls = mm[mm$spic=='sar',10]; vcs = c(lc,ls)
nc = length(lc) ; ns = length(ls)
n2 = nc+1 ; n3 = nc+ns
mcs = abs(mean(vcs[1:nc])-mean(vcs[n2:n3])) # оценка Кри
ma=c(5000)
# резервируем вектор для оценок
for (i in 0:5000)
# оценки Крв
ma[i]=(abs(mean(sample(vcs[1:n3],size=nc))mean(sample(vcs[1:n3],size=ns))))
hist(ma, main="Распределение разности средних",
ylab='Частота',xlab='Разность')
(q95=quantile(ma, prob=c(0.025,0.975)))
quantile(ma, prob=c(0.05,0.95))
ifelse(q95[2]<mcs, 'отличие значимо', ' отличие не значимо')
После запуска скрипта на мониторе получаем следующие сообщения.
> setwd('c:/r/micro_mammal_goms')
> ml = read.csv("mamm.csv")
> mm = na.omit(ml)
> lc = mm[mm$spic=='clg',10] ; ls = mm[mm$spic=='sar',10] # отбор особей
> nc = length(lc) ; ns = length(ls); n3 = nc+ns # подсчет объемов выборок
> vcs = c(lc,ls) # объединение выборок в прото-псевдо-генеральную сов-ть
> (mcs = abs(mean(lc)-mean(ls)))# оценка Кри
[1] 1.714286
> ma=c(5000)
# резервируем вектор для оценок
> for (i in 0:5000)
# оценки Крв
+ ma[i]=(abs(mean(sample(vcs[1:n3],size=nc))+ mean(sample(vcs[1:n3],size=ns))))
> hist(ma, main="Распределение разности средних",
+ ylab='Частота',xlab='Разность')
> (q95=quantile(ma, prob=c(0.025,0.975)))
2.5%
97.5%
0.05555556 3.34126984
> quantile(ma, prob=c(0.05,0.95))
5%
95%
0.0952381 2.9285714
> ifelse(q95[2]<mcs, 'средние отличаются значимо', 'средние значимо не отличаются')
97.5%
"средние значимо не отличаются"
------------------------------------------------------------------Кантиль распределения 5000 значений разности случайных выборок из объединенной выборки (для доверительной вероятности P = 0.95) составляет Крв0.975 = 2.92, фактическое же различие между параметрами составляет Кри = 1.71. Это значение входит в
диапазон возможных случайных различий между двумя выборками. Пока нет оснований
утверждать, что выборки взяты из разных генеральных совокупностей (даже с веро-
18
ятностью P = 0.9). Различий между полевками и бурозубками по длине хвоста обнаружить
не удалось.
Бутстреп можно использовать в тех областях, для которых вовсе не разработаны
процедуры статистических сравнений, например для сравнения видовых списков. Для
примера рассмотрим сравнение встречаемости 25 видов жуков на 4-х трупах млекопитающих (m) и 3-х трупах птиц (b) в Березняке (B). Данные по численности встреченных 25
видов жуков введены в файл zhuk.csv.
,Bm1,Bm2,Bm3,Bm4,Bb1,Bb2,Bf,Bb3,Bmm
Pteros,0,0,0,0,0,1,1,0,1
Crypto,0,0,0,0,0,0,0,0,2
C. imp,2,0,0,0,3,1,0,6,0
C. lat,0,0,0,0,2,4,3,4,10
C. uni,0,0,0,0,0,0,1,0,0
Crypto,0,0,0,1,0,0,0,0,9
Megast,0,0,0,0,0,0,0,0,0
Gnatho,0,0,0,0,0,0,0,0,0
Hister,0,0,0,0,0,0,0,0,1
Margar,3,2,0,0,4,9,6,11,32
M. str,0,0,0,0,0,0,0,0,0
M. ven,0,0,0,0,0,0,0,0,0
Saprin,0,0,0,0,0,0,0,0,0
S. imm,0,0,0,0,0,0,0,0,0
S. pla,0,0,0,0,0,0,0,0,0
S. sem,3,0,0,0,3,4,1,0,5
Apocat,0,0,0,0,0,2,0,0,6
Sciodr,12,13,10,10,23,26,25,24,50
Necrod,0,0,0,0,0,0,0,0,9
Nicrop,6,5,4,0,16,10,5,4,1
N. ves,0,1,0,4,2,3,5,4,0
N. ves,4,7,4,12,9,13,5,10,3
Oiceop,2,4,6,3,10,14,2,14,9
Silpha,0,0,0,0,0,0,0,0,0
S. obs,0,0,0,0,0,0,0,0,0
Идея состоит в том, чтобы отличие усредненного видового состава для млекопитающих (4 особи) и птиц (3 особи) сравнить с распределением отличий между средними
случайно взятых 2 группы данных (4 особи в одной, 3 особи в другой). Выполнение
скрипта дает следующий листинг.
setwd('c:/r')
bz=read.csv("zhuk.csv"); bz[1:4,]
(namz=c(names(bz[,2:7]),"Bb3"))
sz=bz[,namz]
d=c(10000)
dist(rbind(rowSums(sz[,1:4])/4,rowSums(sz[,5:7])/3))
for (i in 0:10000) {sz=bz[,sample(namz)];
d[i]=dist(rbind(rowSums(sz[,1:4])/4,rowSums(sz[,5:7])/3))}
hist(d)
quantile(d, prob=c(0.025,0.975))
quantile(d, prob=c(0.05,0.95))
Читаем файл и видим, что в исходном массиве нужные нам данные занимают семь
векторов со 2 по 7 и 9.
> setwd('c:/r')
> bz=read.csv("zhuk.csv")
> bz[1:4,]
X Bm1 Bm2 Bm3 Bm4 Bb1 Bb2 Bf Bb3 Bmm
1 Pteros
0
0
0
0
0
1 1
0
1
2 Crypto
0
0
0
0
0
0 0
0
2
3 C. imp
2
0
0
0
3
1 0
6
0
4 C. lat
0
0
0
0
2
4 3
4 10
Считываем имена нужных векторов в отдельный массив имен namz. Далее в рабочий массив sz считываем нужные векторы, ориентируясь по этим именам: 4 первых для
маммалий, 3 следующих для птиц. После чего усредняем данные по видам трупов и рас-
19
считываем евклидово расстояние dist() между двумя усредненными векторами. Оно оказалось равным 19.39.
> (namz=c(names(bz[,2:7]),"Bb3"))
[1] "Bm1" "Bm2" "Bm3" "Bm4" "Bb1" "Bb2" "Bb3"
> sz=bz[,namz]
> dist(rbind(rowSums(sz[,1:4])/4,rowSums(sz[,5:7])/3))
1
2 19.39
Подготавливаем массив d для бутстрепа размером 10 000
ячеек и заносим в него
рассчитанные расстояния между средними случайно взятых четырех и трех векторов из
исходной матрицы. Строим гистограмму распределения d и рассчитываем квантили.
> d=c(10000)
> for (i in 0:10000) {sz=bz[,sample(namz)];
+d[i]=dist(rbind(rowSums(sz[,1:4])/4,rowSums(sz[,5:7])/3))}
> hist(d)
> quantile(d, prob=c(0.025,0.975))
2.5% 97.5%
3.25 19.39
> quantile(d, prob=c(0.05,0.95))
5%
95%
3.323945 15.656025
Вопрос о том, на какой уровень вероятности различий следует ориентироваться,
связан с решением, какого типа критерий мы имеем – односторонний или двусторонний?
Поскольку величина евклидовой метрики левым пределом имеет значение 0 (при полном
сходстве объектов), то варьировать она может только с правого края своего распределения. Можно добавить, еще и то соображение, что эта величина не зависит от положения
сравниваемых объектов (сравнивается ли А с Б или Б с А) и призвана выражать только
различия, которые отображаются при удалении от нуля вправо. Это значит, что уместно
применять односторонний критерий, т. е. в соответствии с «соглашением о 95%» ориентироваться на границу 5% только справа. Соответствующая квантиль Крв0.95 = 15. 65. Поскольку исходное расстояние Кри = 19.39 > Крв0.95, различия считаем значимыми (при
p = 0.05). Видовой состав жуков, посещающих трупы животных, отличается для животных
из разных классов.
Литература
R Core Team (2012). R: A language and environment for statistical computing. R Foundation
for Statistical Computing, Vienna, Austria. ISBN 3-900051-07-0, URL http://www.Rproject.org/.
Download