Главная страница

А. Б. Шипунов, Е. М. Балдин, П. А. Волкова, А. И. Коробейников, С. А. Назарова


Скачать 3.04 Mb.
НазваниеА. Б. Шипунов, Е. М. Балдин, П. А. Волкова, А. И. Коробейников, С. А. Назарова
Анкорrbook
Дата29.09.2022
Размер3.04 Mb.
Формат файлаpdf
Имя файлаrbook.pdf
ТипДокументы
#705644
страница6 из 19
1   2   3   4   5   6   7   8   9   ...   19
(что, как вы помните, увеличивает и ее репрезентативность), а также работать с непрерывными данными.
В R интервальные данные представляют в виде числовых векторов
(numerical vectors). Чаще всего один вектор — это одна выборка. Допус- тим, у нас есть данные о росте семи сотрудников небольшой компании.
Вот так можно создать из этих данных простейший числовой вектор:
> x <- c(174, 162, 188, 192, 165, 168, 172.5)
x
— это имя объекта R, «<-» — функция присвоения, c() — функ- ция создания вектора (от англ. concatenate, собрать). Собственно, R и работает в основном с объектами и функциями. У объекта может быть своя структура:
> str(x)
num [1:7] 174 162 188 192 165 168 172.5
То есть x — это числовой (num, «numeric») вектор. В R нет так на- зываемых скаляров, «одиночные» объекты трактуются как векторы из одного элемента. Вот так можно проверить, вектор ли перед нами:
> is.vector(x)
[1] TRUE
Вообще говоря, в R есть множество функций «is.что-то()» для подобной проверки, например:
> is.numeric(x)
[1] TRUE
А еще есть функции конверсии «as.что-то()», с которыми мы по- работаем ниже. Называть объекты можно в принципе как угодно, но лучше придерживаться некоторых правил:

«Садись, двойка»: шкальные данные
49 1. Использовать для названий только латинские буквы, цифры и точку (имена объектов не должны начинаться с точки или циф- ры).
2. Помнить, что R чувствителен к регистру, X и x — это разные имена.
3. Не давать объектам имена, уже занятые распространенными функ- циями (типа c()), а также ключевыми словами (особенно T, F, NA,
NaN
, Inf, NULL, а также pi — единственное встроенное в R число).
Для создания «искусственных» векторов очень полезен оператор
«:», обозначающий интервал, а также функции создания последова- тельностей («sequences») seq() и повторения («replications») rep().
3.2. «Садись, двойка»: шкальные данные
Если интервальные данные можно получить непосредственно (на- пример, посчитать) или при помощи приборов (измерить), то шкальные данные не так просто сопоставить числам. Предположим, нам надо со- ставить, а затем проанализировать данные опросов об удобстве мебели.
Ясно, что «удобство» — вещь субъективная, но игнорировать ее нель- зя, надо что-то с ней сделать. Как правило, «что-то» — это шкала, где каждому баллу соответствует определенное описание, которое и вклю- чается в опрос. Кроме того, в такой шкале все баллы часто можно ран- жировать, в нашем случае — от наименее удобной мебели к наиболее удобной.
Число, которым обозначено значение шкалы,— вещь более чем услов- ная. По сути, можно взять любое число. Зато есть отношение порядка и,
более того, подобие непрерывности. Например, если удобную во всех от- ношениях мебель мы станем обозначать цифрой «5», а несколько менее удобную — цифрой «4», то в принципе можно представить, какая мебель могла бы быть обозначена цифрой «4.5». Именно поэтому к шкальным данным применимы очень многие из тех методов, которые используют- ся для обработки интервальных непрерывных данных. Однако к чис- ловым результатам обработки надо подходить с осторожностью, всегда помнить об условности значений шкалы.
Больше всего трудностей возникает, когда данные измерены в раз- ных шкалах. Разные шкалы часто очень нелегко перевести друг в друга.
По умолчанию R будет распознавать шкальные данные как обычный числовой вектор. Однако для некоторых задач может потребоваться преобразовать его в так называемый упорядоченный фактор («ordered factor» — см. ниже). Если же стоит задача создать шкальные дан-

50
Типы данных ные из интервальных, то можно воспользоваться функцией cut(...,
ordered=TRUE)
Для статистического анализа шкальных данных всегда требуются непараметрические методы. Если же хочется применить параметриче- ские методы, то нужно иначе спланировать сбор данных, чтобы в ре- зультате получить интервальные данные. Например, при исследовани- ях размеров листьев не делить их визуально на «маленькие», «средние»
и «большие», а измерить их длину и ширину при помощи линейки. Од- нако иногда сбор непрерывных данных требует использования трудно- доступного оборудования и сложных методик (например, если вы ре- шите исследовать окраску цветков как непрерывную переменную, вам понадобится спектрофотометр для измерения длины волны отражен- ного света — количественного выражения видимого цвета). В этом слу- чае можно выйти из положения путем последующего перекодирования данных на стадии их обработки. Например, цвет можно закодировать в значениях красного, зеленого и синего каналов компьютерной цветовой шкалы RGB.
Вот еще один пример перекодирования. Предположим, вы изучае- те высоту зданий в различных городах земного шара. Можно в графе
«город» написать его название (номинальные данные). Это, конечно,
проще всего, но тогда вы не сможете использовать эту переменную в статистическом анализе данных. Можно закодировать города цифрами в порядке их расположения, например с севера на юг (если вас инте- ресует географическая изменчивость высоты зданий в городе),— тогда получатся шкальные данные, которые можно обработать непараметри- ческими методами. И наконец, каждый город можно обозначить его географическими координатами или расстоянием от самого южного го- рода — тогда мы получим интервальные данные, которые можно будет попробовать обработать параметрическими методами.
3.3. Красный, желтый, зеленый: номинальные данные
Номинальные данные (их часто называют «категориальными»), в отличие от шкальных, нельзя упорядочивать. Поэтому они еще даль- ше от чисел в строгом смысле слова, чем шкальные данные. Вот, на- пример, пол. Даже если мы присвоим мужскому и женскому полам какие-нибудь числовые значения (например, 1 и 2), то из этого не будет следовать, что какой-то пол «больше» другого. Да и промежуточное значение (1.5) здесь непросто представить.

Красный, желтый, зеленый: номинальные данные
51
В принципе, можно обозначать различные номинальные показатели не цифрами, а буквами, целыми словами или специальными значками —
суть от этого не изменится.
Обычные численные методы для номинальных данных непримени- мы. Однако существуют способы их численной обработки. Самый прос- той — это счет, подсчет количеств данных разного типа в общем массиве данных. Эти количества и производные от них числа уже гораздо легче поддаются обработке.
Особый случай как номинальных, так и шкальных данных — би- нарные данные
, то есть такие, которые проще всего передать числами
0 и 1. Например, ответы «да» и «нет» на вопросы анкеты. Или на- личие/отсутствие чего-либо. Бинарные данные иногда можно упорядо- чить (скажем, наличие и отсутствие), иногда — нет (скажем, верный и неверный ответы). Можно бинарные данные представить и в виде
«логического вектора», то есть набора значений TRUE или FALSE. Са- мая главная польза от бинарных данных — в том, что в них можно перекодировать практически все остальные типы данных (хотя иногда при этом будет потеряна часть информации). После этого к ним можно применять специальные методы анализа, например логистическую ре- грессию (см. главу о двумерных данных) или бинарные коэффициенты сходства (см. главу о многомерных данных).
Для обозначения номинальных данных в R есть несколько способов,
разной степени «правильности». Во-первых, можно создать текстовый
(character) вектор:
> sex <- c("male", "female", "male", "male", "female", "male",
+ "male")
> is.character(sex)
[1] TRUE
> is.vector(sex)
[1] TRUE
> str(sex)
chr [1:7] "male" "female" "male" "male" "female" "male" ...
Обратите внимание на функцию str()! Это очень важная функция,
мы бы рекомендовали выучить ее одной из первых. На первых порах пользователь R не всегда понимает, с каким типом объекта (вектором,
таблицей, списком и т. п.) он имеет дело. Разрешить сомнения помогает str()
Предположим теперь, что sex — это описание пола сотрудников небольшой организации. Вот как R выводит содержимое этого векто- ра:
> sex

52
Типы данных
[1] "male"
"female" "male"
"male"
"female" "male"
"male"
Кстати, пора раскрыть загадку единицы в квадратных скобках —
это просто номер элемента вектора. Вот как его можно использовать
(да-да, квадратные скобки — это тоже команда, можно это проверить,
набрав помощь ?"["):
> sex[1]
[1] "male"
«Умные», то есть объект-ориентированные, команды R кое-что по- нимают про объект sex, например команда table():
> table(sex)
sex female male
2 5
А вот команда plot(), увы, не умеет ничего хорошего сделать с таким вектором. Сначала нужно сообщить R, что этот вектор надо рас- сматривать как фактор (то есть номинальный тип данных). Делается это так:
> sex.f <- factor(sex)
> sex.f
[1] male female male male female male male
Levels: female male
И теперь команда plot() уже «понимает», что ей надо делать —
строить столбчатую диаграмму (рис. 5):
> plot(sex.f)
Это произошло потому, что перед нами специальный тип объекта,
предназначенный для категориальных данных,— фактор с двумя уров- нями (градациями) (levels):
> is.factor(sex.f)
[1] TRUE
> is.character(sex.f)
[1] FALSE
> str(sex.f)
Factor w/ 2 levels "female","male": 2 1 2 2 1 2 2

Красный, желтый, зеленый: номинальные данные
53
female male
0 1
2 3
4 5
Рис. 5. Вот так команда plot() рисует фактор
Очень многие функции R (скажем, тот же самый plot()) предпо- читают факторы текстовым векторам, при этом некоторые умеют кон- вертировать текстовые векторы в факторы, а некоторые — нет, поэтому надо быть внимательным. Еще несколько свойств факторов надо знать заранее. Во-первых, подмножество фактора — это фактор с тем же ко- личеством уровней, даже если их в подмножестве не осталось:
> sex.f[5:6]
[1] female male
Levels: female male
> sex.f[6:7]
[1] male male
Levels: female male
«Избавиться» от лишнего уровня можно, применив специальный ар- гумент или выполнив преобразование данных «туда и обратно»:
> sex.f[6:7, drop=TRUE]

54
Типы данных
[1] male male
Levels: male
> factor(as.character(sex.f[6:7]))
[1] male male
Levels: male
Во-вторых, факторы (в отличие от текстовых векторов) можно лег- ко преобразовать в числовые значения:
> as.numeric(sex.f)
[1] 2 1 2 2 1 2 2
Зачем это нужно, становится понятным, если рассмотреть вот та- кой пример. Положим, кроме роста, у нас есть еще и данные по весу сотрудников:
> w <- c(69, 68, 93, 87, 59, 82, 72)
И мы хотим построить такой график, на котором были бы видны одновременно рост, вес и пол. Вот как это можно сделать (рис. 6):
> plot(x, w, pch=as.numeric(sex.f), col=as.numeric(sex.f))
> legend("topleft", pch=1:2, col=1:2, legend=levels(sex.f))
Тут, разумеется, нужно кое-что объяснить. pch и col — эти пара- метры предназначены для определения соответственно типа значков и их цвета на графике. Таким образом, в зависимости от того, какому полу принадлежит данная точка, она будет изображена кружком или треугольником и черным или красным цветом. При условии, разумеет- ся, что все три вектора соответствуют друг другу. Еще надо отметить,
что изображение пола при помощи значка и цвета избыточно, для «нор- мального» графика хватит и одного из этих способов.
В-третьих, факторы можно упорядочивать, превращая их в один из вариантов шкальных данных. Введем четвертую переменную — размер маек для тех же самых гипотетических восьмерых сотрудников:
> m <- c("L", "S", "XL", "XXL", "S", "M", "L")
> m.f <- factor(m)
> m.f
[1] L
S
XL
XXL S
M
L
Levels: L M S XL XXL
Как видим, уровни расположены просто по алфавиту, а нам надо,
чтобы S (small) шел первым. Кроме того, надо как-то сообщить R, что перед нами — шкальные данные. Делается это так:

Красный, желтый, зеленый: номинальные данные
55 165 170 175 180 185 190 60 65 70 75 80 85 90
female male
Рис. 6. График, показывающий одновременно три переменные
> m.o <- ordered(m.f, levels=c("S", "M", "L", "XL", "XXL"))
> m.o
[1] L
S
XL
XXL S
M
L
Levels: S < M < L < XL < XXL
Теперь R «знает», какой размер больше. Это может сыграть крити- ческую роль — например, при вычислениях коэффициентов корреля- ции.
Работая с факторами, нужно помнить и об одной опасности. Если возникла необходимость перевести фактор в числа, то вместо значений вектора мы получим числа, соответствующие уровням фактора! Чтобы этого не случилось, надо сначала преобразовать фактор, состоящий из значений-чисел, в текстовый вектор, а уже потом — в числовой:
> a <- factor(3:5)
> a
[1] 3 4 5
Levels: 3 4 5

56
Типы данных
> as.numeric(a) # Неправильно!
[1] 1 2 3
> as.numeric(as.character(a)) # Правильно!
[1] 3 4 5
Когда файл данных загружается при помощи команды read.table(),
то все столбцы, где есть хотя бы одно нечисло, будут преобразованы в факторы
1
. Если хочется этого избежать (для того, например, чтобы не столкнуться с вышеописанной проблемой), то нужно задать дополни- тельный параметр: read.table(..., as.is=TRUE).
3.4. Доли, счет и ранги: вторичные данные
Из названия ясно, что такие данные возникают в результате обра- ботки первичных, исходных данных.
Наибольшее применение вторичные данные находят при обработке шкальных и в особенности номинальных данных, которые нельзя обра- батывать «в лоб». Например, счет («counts») — это просто количество членов какой-либо категории. Такие подсчеты и составляют суть ста- тистики в бытовом смысле этого слова. Проценты (доли, «rates») тоже часто встречаются в быту, так что подробно описывать их, наверное, не нужно. Одно из самых полезных их свойств — они позволяют вычле- нить числовые закономерности там, где исходные данные отличаются по размеру.
Для того чтобы визуализировать счет и проценты, придумано нема- ло графических способов. Самые из них распространенные — это, на- верное, графики-пироги и столбчатые диаграммы. Почти любая компью- терная программа, имеющая дело с таблицами данных, умеет строить такие графики. Однако надо заметить, что столбчатые диаграммы и в особенности «пироги» — неудачный способ представления информа- ции. Многочисленные эксперименты доказали, что читаются такие гра- фики гораздо хуже остальных. Самое печальное, что главная задача графиков — показать, где цифры различаются, а где сходны, практи- чески не выполняется. В экспериментах людям предлагали несколько минут смотреть на такие графики, а затем просили расположить груп- пы, отраженные на графике, в порядке значений подсчитанного при- знака. Оказалось, что это нелегко сделать. Вот пример. На рисунке 7 —
столбчатый график результатов гадания на ромашках:
> romashka.t <- read.table("data/romashka.txt", sep="\t")
> romashka <- romashka.t$V2 1
Это верно только для версий R меньше 4.

Доли, счет и ранги: вторичные данные
57
> names(romashka) <- romashka.t$V1
> oldpar <- par(mar = c(7, 4, 4, 2) + 0.1)
> romashka.plot <- barplot(romashka, names.arg="")
> text(romashka.plot, par("usr")[3]-0.25, srt=45, adj=1,
+ xpd=TRUE, labels=names(romashka))
> par(oldpar)
(Пришлось исхитриться, чтобы поместить длинные надписи под стол- биками.)
0 5
10 15 20
лю би т
не лю би т
пл юн ет по це лу ет к с ер дц у п ри жм ет к ч ер ту по шл ет
Рис. 7. Результаты гадания на ромашках (проценты исходов), показан- ные с помощью столбчатой диаграммы
Попробуйте проделать тот же эксперимент: посмотреть на график
3–5 минут, а затем закрыть книгу и расположить возможные исходы гадания в порядке убывания, от самого большого значения — к самому маленькому. (Ответ проверьте в конце главы.)
Создатели R прекрасно знали об этих проблемах, и поэтому в первых версиях вообще не было команды для рисования «пирогов». На замену им, а также на замену менее сомнительным столбчатым диаграммам

58
Типы данных в R есть так называемые точечные графики (dotplots). Ниже приведен пример такого графика для тех же самых данных по гаданию (рис. 8):
> dotchart(romashka)
любит не любит плюнет поцелует к сердцу прижмет к черту пошлет
14 16 18 20 22 24
Рис. 8. Результаты гадания на ромашках (проценты исходов), показан- ные с помощью точечного графика
Надеемся, что большинство читателей согласятся с нами в том, что точечные диаграммы читаются легче «пирогов». Именно поэтому про- фессионалы рекомендуют точечные графики и боксплоты, а не «пиро- ги» и столбчатые диаграммы.
Если счет и доли получают обычно из номинальных данных, то от- ношения и ранги «добывают» из данных количественных. Отношения особенно полезны в тех случаях, когда изучаемые явления или вещи имеют очень разные абсолютные характеристики. Например, вес людей довольно трудно использовать в медицине напрямую, а вот соотноше- ние между ростом и весом очень помогает в диагностике ожирения.
Чтобы получить ранги, надо упорядочить данные по возрастанию и заменить каждое значение на номер его места в полученном ряду.

Пропущенные данные
59
Например, обычная методика вычисления медианы (см. ниже) осно- вывается на рангах. Ранги особенно широко применяются при анализе шкальных и непараметрических интервальных данных. Ранговые ме- тодики анализа, как правило, устойчивы, но менее чувствительны, чем параметрические. Это и понятно, ведь в процессе присваивания рангов часть информации теряется:
> a1 <- c(1,2,3,4,4,5,7,7,7,9,15,17)
> a2 <- c(1,2,3,4,5,7,7,7,9,15,17)
> names(a1) <- rank(a1)
> a1 1
2 3 4.5 4.5 6
8 8
8 10 11 12 1
2 3
4 4
5 7
7 7
9 15 17
> names(a2) <- rank(a2)
> a2 1
2 3
4 5
7 7
7 9 10 11 1
2 3
4 5
7 7
7 9 15 17
Как видно, ранги могут быть не целыми, а половинными. Это бы- вает тогда, когда одинаковых чисел четное число. Кроме того, у одина- ковых чисел ранги тоже одинаковые. Это называется «ties», буквально
«ничья». Ничья эта несколько мешает при выполнении некоторых ста- тистических операций, например при вычислении непараметрических тестов, основанных на рангах:
> wilcox.test(a2)
[... результаты теста пропущены ...]
Warning message:
In wilcox.test.default(a2) : cannot compute exact p-value with ties
В этих случаях R всегда сообщает о проблеме. (О самом тесте речь пойдет в следующей главе.)
1   2   3   4   5   6   7   8   9   ...   19


написать администратору сайта