Переупорядочить данные в таблице, противоположную "расплавлению",
У меня огромный размер данных:
SN = c(1:100, 1:100, 1:100, 1:100)
class = c(rep("A1", 100), rep("B2", 100), rep("C3", 100), rep("D4", 100)) # total 6000 levels
myvar = rnorm(400)
mydf = data.frame(SN, class, myvar)
Я хочу "не расплавить" таблицу с каждым уровнем как один столбец и myvar в заполнении:
SN A1 B2 C3 D4 .............and so on for all 6000
Как я могу достичь этого, я знаю, что это простой вопрос, но я не мог понять.
Ответы
Ответ 1
> dcast(mydf, SN ~ class)
SN A1 B2 C3 D4
1 1 0.1461258 0.8325014 0.33562088 -0.07294576
2 2 0.5964182 0.4593710 -0.23652803 -1.52539568
3 3 2.0247742 -1.1235963 1.79875447 -1.87462227
4 4 0.8184004 1.3486721 0.76076486 -1.18311991
5 5 -0.6577212 0.3666741 -0.06057506 1.38825487
6 6 0.1590443 0.2043661 0.08161778 0.10421797
...
Ответ 2
molten = melt( mydf , id.vars = c( "SN" , "class" ) , measure.vars = "myvar" )
casted = dcast( molten , SN~class )
Ответ 3
В базе R вы можете сделать это вот так:
# get it sorted so that all you need to do is make a matrix out of it
mydf <- mydf[order(mydf$class, mydf$SN),]
# save the unique values of SN
SNu <- unique(mydf$SN)
# combine a matrix with SN
mydfw <- data.frame(SNu, matrix(mydf$myvar, nrow = length(SNu)))
# name your columns
colnames(mydfw) <- c('SN', levels(mydf$class))
Или, для более сжатого выражения с использованием агрегата
aggregate(myvar~SN, mydf, 'c')
# column names don't come out great
colnames(mydfw) <- c('SN', levels(mydf$class))
Ответ 4
Другой подход с split
:
mydfSplit <- split(mydf[,-2], mydf$class, drop=TRUE)
Результат - это список, который можно легко преобразовать в data.frame
, если компоненты имеют одинаковые размеры (что в данном примере истинно):
mydf2 <- do.call(cbind, mydfSplit)
Проблема с этим решением заключается в том, что имена конечного результата нуждаются в очистке. Однако для более общих данных это может быть полезно, если SN
для каждого класса отличается.