Как изменить форму данных из длинного в широкий формат?
у меня возникли проблемы с перестановкой следующего фрейма данных:
set.seed(45)
dat1 <- data.frame(
name = rep(c("firstName", "secondName"), each=4),
numbers = rep(1:4, 2),
value = rnorm(8)
)
dat1
name numbers value
1 firstName 1 0.3407997
2 firstName 2 -0.7033403
3 firstName 3 -0.3795377
4 firstName 4 -0.7460474
5 secondName 1 -0.8981073
6 secondName 2 -0.3347941
7 secondName 3 -0.5013782
8 secondName 4 -0.1745357
Я хочу изменить его так, чтобы каждая уникальная переменная "имя" была именем строки, с "значениями" в качестве наблюдений вдоль этой строки и "числами" в качестве colnames. Примерно так:
name 1 2 3 4
1 firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474
5 secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
Я посмотрел на melt
и cast
и несколько других вещей, но никто, кажется, чтобы сделать работу.
9 ответов:
новый (2014 года)
tidyr
пакет также делает это просто, сgather()
/spread()
будучи термины дляmelt
/cast
.library(tidyr) spread(dat1, key = numbers, value = value)
С github,
tidyr
- это рефреймингreshape2
конструировал сопроводить аккуратную структуру данных, и работать рука об руку сmagrittr
иdplyr
построить твердый трубопровод для анализа данных.как
reshape2
меньше, чем перекраивать,tidyr
не менееreshape2
. Он разработан специально для очистки данных, а не общей перестройки, чтоreshape2
делает, или общее агрегирование, которое изменило форму. В частности, встроенные методы работают только для фреймов данных, иtidyr
не предоставляет никаких полей или агрегации.
другой вариант, если производительность является проблемой, чтобы использовать
data.table
расширениеreshape2
' s melt & dcast функции(ссылка: эффективное изменение формы с использованием данных.таблицы)
library(data.table) setDT(dat1) dcast(dat1, name ~ numbers, value.var = "value") # name 1 2 3 4 # 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078 # 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814
и, по данным.таблица v1.9. 6 мы можем привести на несколько столбцов
## add an extra column dat1[, value2 := value * 2] ## cast multiple value columns dcast(dat1, name ~ numbers, value.var = c("value", "value2")) # name value_1 value_2 value_3 value_4 value2_1 value2_2 value2_3 value2_4 # 1: firstName 0.1836433 -0.8356286 1.5952808 0.3295078 0.3672866 -1.6712572 3.190562 0.6590155 # 2: secondName -0.8204684 0.4874291 0.7383247 0.5757814 -1.6409368 0.9748581 1.476649 1.1515627
другие два варианта:
базовый пакет:
df <- unstack(dat1, form = value ~ numbers) rownames(df) <- unique(dat1$name) df
sqldf
пакет:library(sqldf) sqldf('SELECT name, MAX(CASE WHEN numbers = 1 THEN value ELSE NULL END) x1, MAX(CASE WHEN numbers = 2 THEN value ELSE NULL END) x2, MAX(CASE WHEN numbers = 3 THEN value ELSE NULL END) x3, MAX(CASE WHEN numbers = 4 THEN value ELSE NULL END) x4 FROM dat1 GROUP BY name')
использование базы R
aggregate
функция:aggregate(value ~ name, dat1, I) # name value.1 value.2 value.3 value.4 #1 firstName 0.4145 -0.4747 0.0659 -0.5024 #2 secondName -0.8259 0.1669 -0.8962 0.1681
есть очень мощный новый пакет от genius data scientists в Win-Vector (люди, которые сделали
vtreat
,seplyr
иreplyr
) позвонилcdata
. Он реализует принципы "скоординированных данных", описанные в документ в этой блоге. Идея заключается в том, что независимо от того, как вы организуете свои данные, должно быть возможно идентифицировать отдельные точки данных с помощью системы "координат данных". Вот отрывок из недавнего поста в блоге Джона Гора:вся система основана на двух примитивах или операторах cdata::moveValuesToRowsD() и cdata:: moveValuesToColumnsD(). Эти операторы поворота, ООН-поворотные, одна-горячая кодирования, транспонировать, двигаясь несколько строк и столбцов, а также многие другие преобразования, как простые специальные случаи.
легко написать много различных операций с точки зрения примитивы cdata. Эти операторы могут работать-в памяти или на больших данных масштаб (с базами данных и Apache Spark; для больших данных используйте cdata:: moveValuesToRowsN () и cdata:: moveValuesToColumnsN() варианты.) Преобразования управляются управляющей таблицей, которая сама по себе является диаграммой (или картиной) преобразования.
сначала мы построим таблицу управления (см. блоге для деталей), а затем выполните перемещение данных из строк в столбцы.
library(cdata) # first build the control table pivotControlTable <- buildPivotControlTableD(table = dat1, # reference to dataset columnToTakeKeysFrom = 'numbers', # this will become column headers columnToTakeValuesFrom = 'value', # this contains data sep="_") # optional for making column names # perform the move of data to columns dat_wide <- moveValuesToColumnsD(tallTable = dat1, # reference to dataset keyColumns = c('name'), # this(these) column(s) should stay untouched controlTable = pivotControlTable# control table above ) dat_wide #> name numbers_1 numbers_2 numbers_3 numbers_4 #> 1 firstName 0.3407997 -0.7033403 -0.3795377 -0.7460474 #> 2 secondName -0.8981073 -0.3347941 -0.5013782 -0.1745357
базовый
reshape
функция работает отлично:df <- data.frame( year = c(rep(2000, 12), rep(2001, 12)), month = rep(1:12, 2), values = rnorm(24) ) df_wide <- reshape(df, idvar="year", timevar="month", v.names="values", direction="wide", sep="_") df_wide
здесь
idvar
это столбец классов, который разделяет строкиtimevar
это столбец классов, чтобы бросить широкийv.names
столбец, содержащий числовые значенияdirection
указывает широкий или длинный формат- необязательный элемент - это! Элемент
timevar
иv.names
часть очень легко. Выход этой функции более предсказуем, чем некоторые другие, поскольку все явно определено.