Ответ 1
Почему не просто melt
и dcast
data.table
?
dcast(melt(mydata, id.vars = "col0"), variable ~ col0)
# variable row1 row2 row3
# 1: col1 11 21 31
# 2: col2 12 22 32
# 3: col3 13 23 33
Мне часто нужно транспонировать a data.table
, каждый раз, когда требуется несколько строк кода, и мне интересно, есть ли лучшее решение, чем мое.
если взять таблицу образцов
library(data.table)
mydata <- data.table(col0=c("row1","row2","row3"),
col1=c(11,21,31),
col2=c(12,22,32),
col3=c(13,23,33))
mydata
# col0 col1 col2 col3
# row1 11 12 13
# row2 21 22 23
# row3 31 32 33
и просто транспонируйте его с помощью t()
, он будет перенесен в матрицу с преобразованием в тип character
, а применение data.table
к такой матрице потеряет row.names
:
t(mydata)
# [,1] [,2] [,3]
# col0 "row1" "row2" "row3"
# col1 "11" "21" "31"
# col2 "12" "22" "32"
# col3 "13" "23" "33"
data.table(t(mydata))
# V1 V2 V3
# row1 row2 row3
# 11 21 31
# 12 22 32
# 13 23 33
поэтому мне пришлось написать для этого функцию:
tdt <- function(inpdt){
transposed <- t(inpdt[,-1,with=F]);
colnames(transposed) <- inpdt[[1]];
transposed <- data.table(transposed, keep.rownames=T);
setnames(transposed, 1, names(inpdt)[1]);
return(transposed);
}
tdt(mydata)
# col0 row1 row2 row3
# col1 11 21 31
# col2 12 22 32
# col3 13 23 33
есть ли что-нибудь, что я мог бы оптимизировать здесь или сделать это "лучше"?
Почему не просто melt
и dcast
data.table
?
dcast(melt(mydata, id.vars = "col0"), variable ~ col0)
# variable row1 row2 row3
# 1: col1 11 21 31
# 2: col2 12 22 32
# 3: col3 13 23 33
Здесь альтернативное решение, которое использует только data.table
, и это ближе к исходной идее использования t
для транспонирования.
mydata[, data.table(t(.SD), keep.rownames=TRUE), .SDcols=-"col0"]
## rn V1 V2 V3
## 1: col1 11 21 31
## 2: col2 12 22 32
## 3: col3 13 23 33
Если важно сохранить имена розеток, можно использовать setnames
. По общему признанию, это становится немного неуклюжим и, вероятно, предпочтительным является решение для перестройки.
setnames(mydata[, data.table(t(.SD), keep.rownames=TRUE), .SDcols=-"col0"],
mydata[, c('rn', col0)])[]
## rn row1 row2 row3
## 1: col1 11 21 31
## 2: col2 12 22 32
## 3: col3 13 23 33
текущие документы показывают встроенный метод transpose
. Я не знаю, когда он был добавлен, но, по-видимому, это было необходимо!
Здесь используется решение, которое использует обертку для вывода вывода функции data.table transpose
.
С действительно большими наборами данных это, по-видимому, более эффективно, чем метод dcast/melt (я тестировал его на наборе данных столбцов размером 8000 строк х 29000, функция ниже работает примерно через 3 минуты, но dcast/melt crashed R):
# Function to clean up output of data.table transpose:
transposedt <- function(dt, varlabel) {
require(data.table)
dtrows = names(dt)
dtcols = as.list(c(dt[,1]))
dtt = transpose(dt)
dtt[, eval(varlabel) := dtrows]
setnames(dtt, old = names(dtt), new = c(dtcols[[1]], eval(varlabel)))
dtt = dtt[-1,]
setcolorder(dtt, c(eval(varlabel), names(dtt)[1:(ncol(dtt) - 1)]))
return(dtt)
}
# Some dummy data
mydt <- data.table(col0 = c(paste0("row", seq_along(1:100))),
col01 = c(sample(seq_along(1:100), 100)),
col02 = c(sample(seq_along(1:100), 100)),
col03 = c(sample(seq_along(1:100), 100)),
col04 = c(sample(seq_along(1:100), 100)),
col05 = c(sample(seq_along(1:100), 100)),
col06 = c(sample(seq_along(1:100), 100)),
col07 = c(sample(seq_along(1:100), 100)),
col08 = c(sample(seq_along(1:100), 100)),
col09 = c(sample(seq_along(1:100), 100)),
col10 = c(sample(seq_along(1:100), 100)))
# Apply the function:
mydtt <- transposedt(mydt, "myvariables")
# View the results:
> mydtt[,1:10]
myvariables row1 row2 row3 row4 row5 row6 row7 row8 row9
1: col01 58 53 14 96 51 30 26 15 68
2: col02 6 72 46 62 69 9 63 32 78
3: col03 21 36 94 41 54 74 82 64 15
4: col04 68 41 66 30 31 78 51 67 26
5: col05 49 30 52 78 73 71 5 66 44
6: col06 89 35 79 67 6 88 62 97 73
7: col07 66 15 27 29 58 40 35 82 57
8: col08 55 47 83 30 23 65 48 56 87
9: col09 41 10 21 33 55 81 94 25 34
10: col10 35 17 41 44 21 66 69 61 46
Что также полезно, так это то, что столбцы (ex rows) встречаются в их первоначальном порядке, и вы можете назвать столбцы переменных чем-то значимым.