R Language
Перестановка данных между длинными и широкими формами
Поиск…
Вступление
В R табличные данные хранятся в кадрах данных . В этом разделе рассматриваются различные способы преобразования одной таблицы.
замечания
Полезные пакеты
- Реорганизация, укладка и разбиение на data.table
- Изменить форму tidyr
- splitstackshape
Функция изменения формы
Наиболее гибкая базовая функция R для переформатирования данных reshape
. См. « ?reshape
его синтаксис».
# create unbalanced longitudinal (panel) data set
set.seed(1234)
df <- data.frame(identifier=rep(1:5, each=3),
location=rep(c("up", "down", "left", "up", "center"), each=3),
period=rep(1:3, 5), counts=sample(35, 15, replace=TRUE),
values=runif(15, 5, 10))[-c(4,8,11),]
df
identifier location period counts values
1 1 up 1 4 9.186478
2 1 up 2 22 6.431116
3 1 up 3 22 6.334104
5 2 down 2 31 6.161130
6 2 down 3 23 6.583062
7 3 left 1 1 6.513467
9 3 left 3 24 5.199980
10 4 up 1 18 6.093998
12 4 up 3 20 7.628488
13 5 center 1 10 9.573291
14 5 center 2 33 9.156725
15 5 center 3 11 5.228851
Обратите внимание, что data.frame несимметричен, то есть в блоке 2 отсутствует наблюдение в первом периоде, тогда как в блоках 3 и 4 отсутствуют наблюдения во втором периоде. Также обратите внимание, что в течение периодов есть две переменные: количество и значения, а также два значения, которые не различаются: идентификатор и местоположение.
Длинные
Чтобы изменить формат data.frame на широкий формат,
# reshape wide on time variable
df.wide <- reshape(df, idvar="identifier", timevar="period",
v.names=c("values", "counts"), direction="wide")
df.wide
identifier location values.1 counts.1 values.2 counts.2 values.3 counts.3
1 1 up 9.186478 4 6.431116 22 6.334104 22
5 2 down NA NA 6.161130 31 6.583062 23
7 3 left 6.513467 1 NA NA 5.199980 24
10 4 up 6.093998 18 NA NA 7.628488 20
13 5 center 9.573291 10 9.156725 33 5.228851 11
Обратите внимание, что отсутствующие периоды времени заполняются НС.
При изменении ширины аргумент «v.names» указывает столбцы, которые меняются со временем. Если переменная местоположения не нужна, ее можно отбросить до изменения с аргументом «drop». При отбрасывании единственного столбца без изменения / non-id из файла data.fram аргумент v.names становится ненужным.
reshape(df, idvar="identifier", timevar="period", direction="wide",
drop="location")
Широкий и длинный
Чтобы изменить длину с текущей df.wide, минимальный синтаксис
reshape(df.wide, direction="long")
Однако это обычно сложнее:
# remove "." separator in df.wide names for counts and values
names(df.wide)[grep("\\.", names(df.wide))] <-
gsub("\\.", "", names(df.wide)[grep("\\.", names(df.wide))])
Теперь простой синтаксис приведет к ошибке об неопределенных столбцах.
С именами столбцов, которые сложнее для функции reshape
автоматически анализировать, иногда необходимо добавить «переменный» аргумент, который говорит reshape
для группировки определенных переменных в широком формате для преобразования в длинный формат. Этот аргумент принимает список векторов имен переменных или индексов.
reshape(df.wide, idvar="identifier",
varying=list(c(3,5,7), c(4,6,8)), direction="long")
При долгой перестройке аргумент «v.names» может быть предоставлен для переименования полученных переменных.
Иногда спецификацию «меняющегося» можно избежать с помощью аргумента «sep», который говорит о том, чтобы reshape
какая часть имени переменной указывает аргумент значения и который определяет аргумент времени.
Изменение формы данных
Часто данные поступают в таблицы. Как правило, можно разделить эти табличные данные в широком и длинном форматах. В широком формате каждая переменная имеет свой собственный столбец.
Человек | Высота (см] | Возраст [год] |
---|---|---|
Alison | 178 | 20 |
боб | 174 | 45 |
деревенщина | 182 | 31 |
Однако иногда удобнее иметь длинный формат, в котором все переменные находятся в одном столбце, а значения находятся во втором столбце.
Человек | переменная | Значение |
---|---|---|
Alison | Высота (см] | 178 |
боб | Высота (см] | 174 |
деревенщина | Высота (см] | 182 |
Alison | Возраст [год] | 20 |
боб | Возраст [год] | 45 |
деревенщина | Возраст [год] | 31 |
Base R, а также сторонние пакеты могут использоваться для упрощения этого процесса. Для каждого из вариантов будет использоваться набор данных mtcars
. По умолчанию этот набор данных имеет длинный формат. Чтобы пакеты работали, мы вставляем имена строк в качестве первого столбца.
mtcars # shows the dataset
data <- data.frame(observation=row.names(mtcars),mtcars)
База R
В базе R есть две функции, которые можно использовать для преобразования между широким и длинным форматом: stack()
и unstack()
.
long <- stack(data)
long # this shows the long format
wide <- unstack(long)
wide # this shows the wide format
Однако эти функции могут стать очень сложными для более сложных случаев использования. К счастью, есть и другие варианты использования сторонних пакетов.
Пакет tidyr
В этом пакете используется gather()
для преобразования из широкоугольного в long и spread()
для преобразования из long в wide.
library(tidyr)
long <- gather(data, variable, value, 2:12) # where variable is the name of the
# variable column, value indicates the name of the value column and 2:12 refers to
# the columns to be converted.
long # shows the long result
wide <- spread(long,variable,value)
wide # shows the wide result (~data)
Пакет data.table
Пакет data.table расширяет функции reshape2
и использует функцию melt()
для перехода от широкого к длинному и dcast()
для перехода от длинного к широкому.
library(data.table)
long <- melt(data,'observation',2:12,'variable', 'value')
long # shows the long result
wide <- dcast(long, observation ~ variable)
wide # shows the wide result (~data)