#r #dataframe
#r #dataframe
Вопрос:
Предположим, у меня есть R dataframe, подобный этому:
Subject Session Property.A Property.B Property.C
1 100 1 -1.22527548 -0.9193751 -1.7501693
2 100 10 2.30627980 1.8940830 -0.8443976
3 100 2 2.33243332 -0.5860868 -4.2074489
4 100 3 0.38130810 -0.7336206 4.8016230
5 100 4 1.44685875 0.5066249 2.0138624
6 100 5 0.08907721 -0.3715202 1.4983700
Я слышал, что этот стиль фрейма данных называется «короткой формой» или «широкой формой». Теперь предположим, что я хочу, чтобы это выглядело следующим образом, который, как я слышал, называется «длинной формой»:
Subject Session Property Value
1 100 1 A -1.2252754
2 100 1 B -0.9193751
3 100 1 C -1.7501693
4 100 2 A 2.3324333
5 100 2 B -0.5860868
6 100 2 C -4.2074489
То есть у меня есть N столбцов, которые я хочу сократить всего до двух столбцов «имя / значение», при этом любые другие столбцы в dataframe будут расширены повторяющимися значениями по мере необходимости.
Очевидно, что я мог бы выполнить это преобразование с помощью множества циклов for, но это кажется действительно уродливым, и было бы больно поддерживать, если / когда я добавлю больше столбцов свойств.
Есть ли способ сделать это в R всего несколькими строками кода? Какая-то волшебная комбинация функций, которую я еще не обнаружил?
Комментарии:
1. Обновление: в настоящее время я поумнел и использую
plyr
для всех своих потребностей в изменении формы данных!2. Как это можно сделать в plyr?
Ответ №1:
Используйте melt
функцию в пакете reshape2
:
library(reshape2)
dat.m <- melt(dat, id.vars = c("Subject", "Session"))
Если вам нужно очистить имена столбцов и / или значения для переменной column:
#change "variable" to "Property"
names(dat.m)[3] <- "Property"
#Drop "Property." from the column values
dat.m$Property <- gsub("Property\.", "", dat.m$Property)
Комментарии:
1. Спасибо, это именно то, что нужно. Сейчас я просматриваю документы пакета reshape, какая отличная концепция. Не знаю, как бы я ВООБЩЕ нашел это путем поиска, используя такую чисто метафорическую, не описательную терминологию, как «расплавленный» и «отлитый». Это кажется такой обычной вещью, которую хочется сделать, как это может не быть частью базовой функциональности R?
2.
reshape
функция в stats поставляется с базовым R и предоставляет, казалось бы, эквивалентную функциональность для расплавления и приведения, хотя я никогда не пытался изучить ее, поскольку синтаксисmelt
иcast
довольно прост в освоении. Что касается поиска по вещам, я думаю, у вас есть немного смысла — к счастью, это ТАК!3. Или используйте
reshape2
, что может быть немного быстрее
Ответ №2:
Мне нравится использовать plyr
функции, но reshape
функция из base довольно мощная, как показано в решении ниже.
# create a dummy data frame
dat = data.frame(
subject = rep(100, 5),
session = sample(5, 10, replace = T),
property.a = rnorm(5),
property.b = rnorm(5),
property.c = rnorm(5)
)
# convert wide to long, varying columns are 3:5, separator is "."
dat.long = reshape(dat, direction = 'long', varying = 3:5, sep = ".")
Комментарии:
1. 1 за это. Я потратил 10 минут, пытаясь заставить эту работу опубликовать в моем ответе в качестве альтернативы, но по пути продолжал увязать.
Ответ №3:
пакет изменения формы для этого отлично подходит для этого, но … куча циклов не является альтернативой.
возможно, этот пример поучителен…
longDF <- lapply( 3:4, function(x) cbind(wideDF[1:2], p = names(wideDF)[x], wideDF[x]) )
longDF <- rbind( longDF )
или этот
longDF <- cbind( rep(wideDF[1], 3), rep(wideDF[2], 3), c(wideDF[3], wideDF[4], wideDF[5]) )