Изменение кадра данных в R
Я сталкиваюсь с трудностями при изменении большого информационного блока. И мне относительно повезло, что я избежал изменения проблем в прошлом, что также означает, что я ужасен в этом.
Мой текущий фрейм данных выглядит примерно так:
unique_id seq response detailed.name treatment
a N1 123.23 descr. of N1 T1
a N2 231.12 descr. of N2 T1
a N3 231.23 descr. of N3 T1
...
b N1 343.23 descr. of N1 T2
b N2 281.13 descr. of N2 T2
b N3 901.23 descr. of N3 T2
...
И я хотел бы:
seq detailed.name T1 T2
N1 descr. of N1 123.23 343.23
N2 descr. of N2 231.12 281.13
N3 descr. of N3 231.23 901.23
Я посмотрел на пакет изменения формы, но я не уверен, как я могу преобразовать факторы обработки в отдельные имена столбцов.
Спасибо!
Изменить: я попытался запустить это на моем локальном компьютере (4 ГБ двухъядерный iMac 3.06 ГГц), и он продолжает отказывать с:
> d.tmp.2 <- cast(d.tmp, `SEQ_ID` + `GENE_INFO` ~ treatments)
Aggregation requires fun.aggregate: length used as default
R(5751) malloc: *** mmap(size=647168) failed (error code=12)
*** error: can't allocate region
*** set a breakpoint in malloc_error_break to debug
Я попробую запустить это на одной из наших больших машин, когда у меня будет шанс.
5 ответов
Reshape всегда кажется мне сложным, но он всегда работает с небольшой пробой и ошибкой. Вот что я в итоге нашел:
> x
unique_id seq response detailed.name treatment
1 a N1 123.23 dN1 T1
2 a N2 231.12 dN2 T1
3 a N3 231.23 dN3 T1
4 b N1 343.23 dN1 T2
5 b N2 281.13 dN2 T2
6 b N3 901.23 dN3 T2
> x2 <- melt(x, c("seq", "detailed.name", "treatment"), "response")
> x2
seq detailed.name treatment variable value
1 N1 dN1 T1 response 123.23
2 N2 dN2 T1 response 231.12
3 N3 dN3 T1 response 231.23
4 N1 dN1 T2 response 343.23
5 N2 dN2 T2 response 281.13
6 N3 dN3 T2 response 901.23
> cast(x2, seq + detailed.name ~ treatment)
seq detailed.name T1 T2
1 N1 dN1 123.23 343.23
2 N2 dN2 231.12 281.13
3 N3 dN3 231.23 901.23
Ваши исходные данные были уже в длинном формате, но не в том длинном формате, который использует расплавление / отливка. Я переплавила его. Второй аргумент (id.vars) - это список вещей, которые нельзя растаять. Третий аргумент (measure.vars) - это список вещей, которые меняются.
Затем приведение использует формулу. Слева от тильды находятся вещи, которые остаются такими, какие они есть, а справа от тильды находятся столбцы, которые используются для подготовки столбца значений.
Более менее...!
Опираясь на ответ Харлана, можно избежать шага переплавки, если данные уже в длинном формате, а значения столбца указаны в cast
вызов.
> x <- read.table(textConnection(" unique_id seq response detailed.name treatment
+ 1 a N1 123.23 dN1 T1
+ 2 a N2 231.12 dN2 T1
+ 3 a N3 231.23 dN3 T1
+ 4 b N1 343.23 dN1 T2
+ 5 b N2 281.13 dN2 T2
+ 6 b N3 901.23 dN3 T2"))
>
> cast(x, seq + detailed.name ~ treatment, value = "response")
seq detailed.name T1 T2
1 N1 dN1 123.23 343.23
2 N2 dN2 231.12 281.13
3 N3 dN3 231.23 901.23
Другой вариант будет использовать spread
от tidyr
library(tidyr)
Wide1 <- spread(x[-1], treatment, response)
Wide1
# seq detailed.name T1 T2
#1 N1 dN1 123.23 343.23
#2 N2 dN2 231.12 281.13
#3 N3 dN3 231.23 901.23
Противоположное действие выполняется gather
gather(Wide1, detailed.name, response, T1:T2)
# seq detailed.name detailed.name response
#1 N1 dN1 T1 123.23
#2 N2 dN2 T1 231.12
#3 N3 dN3 T1 231.23
#4 N1 dN1 T2 343.23
#5 N2 dN2 T2 281.13
#6 N3 dN3 T2 901.23
Также есть dcast.data.table
от data.table
library(data.table)
dcast.data.table(setDT(x), seq + detailed.name~treatment,
value.var='response')
# seq detailed.name T1 T2
#1: N1 dN1 123.23 343.23
#2: N2 dN2 231.12 281.13
#3: N3 dN3 231.23 901.23
данные
x <- structure(list(unique_id = structure(c(1L, 1L, 1L, 2L, 2L, 2L
), .Label = c("a", "b"), class = "factor"), seq = structure(c(1L,
2L, 3L, 1L, 2L, 3L), .Label = c("N1", "N2", "N3"), class = "factor"),
response = c(123.23, 231.12, 231.23, 343.23, 281.13, 901.23
), detailed.name = structure(c(1L, 2L, 3L, 1L, 2L, 3L), .Label = c("dN1",
"dN2", "dN3"), class = "factor"), treatment = structure(c(1L,
1L, 1L, 2L, 2L, 2L), .Label = c("T1", "T2"), class = "factor")), .Names =
c("unique_id", "seq", "response", "detailed.name", "treatment"), class =
"data.frame", row.names = c(NA, -6L))
Вы также можете использовать reshape
функция в stats
пакет. У меня нет вашего образца данных, но он будет выглядеть примерно так:
reshape(x, idvar=c("seq","detailed.name"), timevar="treatment", direction="wide")
Если вы хотите получить те же результаты, используя reshape2
, что является более быстрой и более эффективной перезаписью reshape
пакет, тогда будет работать следующее.
Основным изменением является использование dcast
функционировать, когда вы хотите cast
с data.frame
в качестве вывода. Это заменяет cast
функция reshape
library(reshape2)
x = read.table(text = "unique_id seq response detailed.name treatment
a N1 123.23 dN1 T1
a N2 231.12 dN2 T1
a N3 231.23 dN3 T1
b N1 343.23 dN1 T2
b N2 281.13 dN2 T2
b N3 901.23 dN3 T2",
sep = "", header = TRUE)
x
y <- dcast(x, seq + detailed.name ~ treatment, value.var = "response")
y
# seq detailed.name T1 T2
# 1 N1 dN1 123.23 343.23
# 2 N2 dN2 231.12 281.13
# 3 N3 dN3 231.23 901.23
# EDIT to show how to return to the original data set:
melt(y, id.vars=c('seq', 'detailed.name'), variable.name='T', value.name='response')
# seq detailed.name T response
# 1 N1 dN1 T1 123.23
# 2 N2 dN2 T1 231.12
# 3 N3 dN3 T1 231.23
# 4 N1 dN1 T2 343.23
# 5 N2 dN2 T2 281.13
# 6 N3 dN3 T2 901.23