Пример 1.3(1)

Рассмотрим модельные данные, соответствующие Примеру 1.1.3(2). Напомним, что в этом примере обсуждается два способа оценки скорости чтения: количество прочитанных в минуту знаков и время, затраченное на чтение 1000 знаков. Допустим, что в исследовании скорости чтения приняло участие 19 учеников 2-го класса начальной школы. Модельные результаты такого эксперимента содержатся в файле ReadingSpeed.sav.

R имеет множество функций для чтения данных в самых разнообразных форматах. Воспользуемся одной из таких функций, чтобы получить данные из файла, созданного в статистическом пакете IBM SPSS Statistics.

library(foreign)

df <- read.spss(
  file = "http://mathpsy.com/handbook/files/Chapter%201/ReadingSpeed.sav",
  to.data.frame = TRUE
)
## re-encoding from CP1251

В первой строке при помощи функции library() загружается стандартная библиотека foreign, в которой содержится нужная нам функция read.spss(). Ей мы передаем два аргумента с именами file и to.data.frame. Первый представляет собой имя файла данных, включая его расположение на сайте учебника, а второй указывает функции, что прочитанные из файла данные нужно представить в виде таблицы данных (по умолчанию создается список). Функция возвращает результат, который заносится в объект с именем df.

Добавляем метки переменных

Файл ReadingSpeed.sav не содержит текстовых меток для переменных. Наличие таких меток существенно облегчает работу с большими и незакомыми массивами информации, поэтому в следующем блоке кода установим для каждого столбца прочитанной таблицы данных атрибут с именем label и присвоим ему соответствующее текстовое описание:

attr(df$chars, "label") <- "количество знаков за минуту"
attr(df$t, "label") <- "время на чтение 1000 знаков"
attr(df$charsLN, "label") <- "натуральный логарифм chars"
attr(df$tLN, "label") <- "натуральный логарифм t"

Следует заметить, что в R текстовые метки переменных были введены относительно недавно, поэтому большинство фнукций их не используют при выводе результатов анализа.

Просмотр данных

Чтобы вывести содержимое какого-то объекта на экран, достаточно указать его имя. На самом деле в этот момент неявным образом вызывается функция print(). Иногда бывает полезно использовать эту функцию для вывода, потому что это дает возможность использовать ее дополнительные аргументы. Например, вот так мы можем округлять ичсловые значения: print(df, digits = 3).

df
##    chars        t  charsLN       tLN
## 1    205 4.878049 5.323010 1.5847453
## 2    401 2.493766 5.993961 0.9137939
## 3    356 2.808989 5.874931 1.0328245
## 4    255 3.921569 5.541264 1.3664917
## 5    495 2.020202 6.204558 0.7031975
## 6    492 2.032520 6.198479 0.7092766
## 7    499 2.004008 6.212606 0.6951492
## 8    284 3.521127 5.648974 1.2587810
## 9    518 1.930502 6.249975 0.6577800
## 10   355 2.816901 5.872118 1.0356375
## 11   636 1.572327 6.455199 0.4525567
## 12   491 2.036660 6.196444 0.7113112
## 13   890 1.123596 6.791221 0.1165338
## 14   740 1.351351 6.606650 0.3011051
## 15   372 2.688172 5.918894 0.9888614
## 16   454 2.202643 6.118097 0.7896581
## 17   493 2.028398 6.200509 0.7072461
## 18   446 2.242152 6.100319 0.8074363
## 19   427 2.341920 6.056784 0.8509713

При выполнении данной строки на экране возникает таблица данных, содержащая четыре столбца, названия которых подписаны вверху таблицы. Столбцы называются переменными, а надписи — их именами. При вводе данных исследования каждый столбец содержит информацию об одном из регистрируемых параметров, а каждая строка — информацию об одном испытуемом. В нашем примере первая переменная — chars — это количество знаков, прочитанных испытуемым за минуту, а вторая — t — это время, затрачиваемое испытуемым на чтение 1000 знаков. Показатели связаны соотношением t = 1000/n (см. объяснения в Примере 1.1.3(2). Третья и четвертая переменные представляют собой натуральные логарифмы от первой и второй переменных (charLN и tLN для char и t соответственно). Шкала «число знаков, прочитанных за минуту» с формальной точки зрения интервальная, однако если обратиться к содержательной стороне вопроса, то можно спросить: одинаковы ли в интересующем нас смысле различие между детьми, прочитавшими 200 и 300 знаков за минуту, и различие между детьми, прочитавшими 900 и 1000 знаков? По всей видимости, нет. Такое же рассуждение можно применить и к шкале «время, затрачиваемое на прочтение 1000 знаков».

Имеется еще одна полезная функция View(df), которая открывает внутри RStudio вкладку с электронной таблицей:

Просмотр в виде таблицы

Просмотр в виде таблицы

Еще одну проблему мы уже обсуждали в Примере 1.1.3(2). Здесь мы имеем следующие результаты: самый быстрый ученик (номер 13) прочитал 890 знаков в минуту, а на 1000 знаков потратил 1.12 минуты. Самый медленный ученик (номер 1) прочитал 205 знаков за минуту и потратил на 1000 знаков 4.88 минуты. Занимающий среднюю позицию ученик номер 16 показал результат 454 и 2.20 соответственно.

Упражнение 1.3.(2). К какому из двух полюсов скорости чтения в классе окажется ближе средний ученик (номер 16), если его скорость чтения измерять первым способом и вторым способом?

Не получилось ли у нас, что две «интервальные» шкалы оценивают при таком подходе расстояния между одними и теми же парами испытуемых по-разному?

Упражнение 1.3(3). Если рассмотреть эти, формально претендующие на интервальный тип, шкалы как порядковые, то две шкалы дают один и тот же результат (так как связаны между собой монотонным преобразованием). Чтобы убедиться в этом, проведем следующую операцию. В R есть возможность ранжировать данные. Для этого надо воспользоваться функцией rank(имя_столбца). Ниже приводится фрагмент кода, который с помощью функции transform() выполняет преобразование таблицы данных df — в ней создается новый столбец (переменная) с именем Rchars, в которой хранятся ранги учеников по переменной chars. Проранжируем испытуемых по числу знаков, прочитанных за минуту:

transform(
  df, Rchars = rank(chars)
)
##    chars        t  charsLN       tLN Rchars
## 1    205 4.878049 5.323010 1.5847453      1
## 2    401 2.493766 5.993961 0.9137939      7
## 3    356 2.808989 5.874931 1.0328245      5
## 4    255 3.921569 5.541264 1.3664917      2
## 5    495 2.020202 6.204558 0.7031975     14
## 6    492 2.032520 6.198479 0.7092766     12
## 7    499 2.004008 6.212606 0.6951492     15
## 8    284 3.521127 5.648974 1.2587810      3
## 9    518 1.930502 6.249975 0.6577800     16
## 10   355 2.816901 5.872118 1.0356375      4
## 11   636 1.572327 6.455199 0.4525567     17
## 12   491 2.036660 6.196444 0.7113112     11
## 13   890 1.123596 6.791221 0.1165338     19
## 14   740 1.351351 6.606650 0.3011051     18
## 15   372 2.688172 5.918894 0.9888614      6
## 16   454 2.202643 6.118097 0.7896581     10
## 17   493 2.028398 6.200509 0.7072461     13
## 18   446 2.242152 6.100319 0.8074363      9
## 19   427 2.341920 6.056784 0.8509713      8

В данном случае заказанные преобразования выводятся на экран, но не сохраняются в таблице данных. Для того, чтобы изменения

Обратите внимание на направление ранжирования, оно возможно от наибольшего значения исходной переменной к наименьшему и наоборот. Если мы хотим, чтобы первый ранг получил испытуемый, читающий быстрее всех, то ранг 1 в данном случае надо присвоить наибольшему значению числа прочитанных знаков. Делается это вот так:

## descending order
transform(
  df, Rchars = rank(-chars)
)
##    chars        t  charsLN       tLN Rchars
## 1    205 4.878049 5.323010 1.5847453     19
## 2    401 2.493766 5.993961 0.9137939     13
## 3    356 2.808989 5.874931 1.0328245     15
## 4    255 3.921569 5.541264 1.3664917     18
## 5    495 2.020202 6.204558 0.7031975      6
## 6    492 2.032520 6.198479 0.7092766      8
## 7    499 2.004008 6.212606 0.6951492      5
## 8    284 3.521127 5.648974 1.2587810     17
## 9    518 1.930502 6.249975 0.6577800      4
## 10   355 2.816901 5.872118 1.0356375     16
## 11   636 1.572327 6.455199 0.4525567      3
## 12   491 2.036660 6.196444 0.7113112      9
## 13   890 1.123596 6.791221 0.1165338      1
## 14   740 1.351351 6.606650 0.3011051      2
## 15   372 2.688172 5.918894 0.9888614     14
## 16   454 2.202643 6.118097 0.7896581     10
## 17   493 2.028398 6.200509 0.7072461      7
## 18   446 2.242152 6.100319 0.8074363     11
## 19   427 2.341920 6.056784 0.8509713     12

Упражнение 1.3(4). Проранжируйте испытуемых по времени, затрачиваемому на чтение 1000 знаков. Будьте внимательны, определите направление ранжирования так, чтобы ранг 1 получил наиболее быстро читающий испытуемый. Сопоставьте ранги, получаемые при ранжировании двух шкал, убедитесь, что ранги испытуемых совпадают.

Задание 1.3(5). Еще один вариант, позволяющий сделать оценки по двум шкалам более согласованными — это логарифмирование полученных данных. В переменных charsLN и tLN содержатся натуральные логарифмы значений переменных chars и t соответственно. Как мы писали в примечании к Примеру 1.1.3(2), обе логарифмические шкалы с полным правом могут считаться интервальными. Вопрос: Какое допустимое преобразование переводит первую логарифмическую шкалу во вторую? (Указание: убедитесь, что сумма этих переменных постоянна для всех испытуемых с точностью до округления).

Задание 1.3(6). Испытуемых можно упорядочить по значениям какой-то переменной. Для того, чтобы это сделать, в R нужно воспользоваться функцией order(столбец), которая возвращает последовательность номеров исходных наблюдений в упорядоченном ряду. В первой строке этого фрагмента кода функция order() вызывается для столбца df$chars, при этом второй аргумент явным образом указывает, что упорядочивание должно происходить от большего значения к меньшему (т.е., в убывающем порядке). Возвращаемое функцией значение записывается в объект с именем “o” (не перепутайте с нулем!):

(o <- order(df$chars, decreasing = TRUE))
##  [1] 13 14 11  9  7  5 17  6 12 16 18 19  2 15  3 10  8  4  1
df[o,]
##    chars        t  charsLN       tLN
## 13   890 1.123596 6.791221 0.1165338
## 14   740 1.351351 6.606650 0.3011051
## 11   636 1.572327 6.455199 0.4525567
## 9    518 1.930502 6.249975 0.6577800
## 7    499 2.004008 6.212606 0.6951492
## 5    495 2.020202 6.204558 0.7031975
## 17   493 2.028398 6.200509 0.7072461
## 6    492 2.032520 6.198479 0.7092766
## 12   491 2.036660 6.196444 0.7113112
## 16   454 2.202643 6.118097 0.7896581
## 18   446 2.242152 6.100319 0.8074363
## 19   427 2.341920 6.056784 0.8509713
## 2    401 2.493766 5.993961 0.9137939
## 15   372 2.688172 5.918894 0.9888614
## 3    356 2.808989 5.874931 1.0328245
## 10   355 2.816901 5.872118 1.0356375
## 8    284 3.521127 5.648974 1.2587810
## 4    255 3.921569 5.541264 1.3664917
## 1    205 4.878049 5.323010 1.5847453

Круглые скобки, в которые заключено все выражение, заставляют R вывести на экран содержимое этого объекта. Можно убедиться, что первым в упорядоченном ряду идет ученик с номером 13, затем 14 и т.д. Замыкает ряд ученик с номером 1.

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

Попробуйте самостоятельно создать ранги переменных chars и t, сохранив результаты преобразований в новой таблице данных с именем dfr, а потом отсортируйте ее по стобцу chars. Убедитесь, что упорядоченности по всем переменным и по рангам согласованы.