/ / Як отримати цю dcast'able довгу таблицю в R? - r, структури даних

Як отримати цю dcast'able довгу таблицю в R? - r, структури даних

Я намагаюся подати заявку dcast на довгій таблиці, продовження з відповіді нитки Як отримати цю структуру даних у R? Код

dat.m <- structure(c(150L, 60L, 41L, 61L, 0L, 0L), .Dim = c(3L, 2L), .Dimnames = list(
c("ave_max", "ave", "lepo"), NULL))
library("ggplot2")
library("data.table")
dat.m <- melt(as.data.table(dat.m, keep.rownames = "Vars"), id.vars = "Vars") # https://stackoverflow.com/a/44128640/54964
dat.m

print("New step")
# http://stackoverflow.com/a/44090815/54964
minmax <- dat.m[dat.m$Vars %in% c("ave_max","lepo"), ]
absol  <- dat.m[dat.m$Vars %in% c("ave"), ]
#minm   <- dcast(minmax, Vars ~ variable)
minm   <- dcast(minmax, Vars ~ ...)
absol <- merge(absol, minm, by = "Vars", all.x = T)

absol

#Test function
ggplot(absol, aes(x = Vars, y = value, fill = variable)) +
geom_bar(stat = "identity") +
geom_errorbar(aes(ymin = lepo, ymax = ave_max), width = .25)

Вихідні дані

dcast, melt

Vars variable value
1: ave_max       V1   150
2:     ave       V1    60
3:    lepo       V1    41
4: ave_max       V2    61
5:     ave       V2     0
6:    lepo       V2     0
[1] "New step"
Vars variable value V1 V2
1:  ave       V1    60 NA NA
2:  ave       V2     0 NA NA
Error in FUN(X[[i]], ...) : object "lepo" not found
Calls: <Anonymous> ... by_layer -> f -> <Anonymous> -> f -> lapply -> FUN -> FUN
Execution halted

Очікуваний результат: для проходження тестової функції ggplot

Тестування пропозиції Уве

Мета полягає в тому, щоб дістатись до цієї структури даних

dat.m <- structure(c(150L, 60L, 41L, 61L, 0L, 0L), .Dim = c(3L, 2L), .Dimnames = list(c("ave_max", "ave", "lepo"), NULL))

з цієї структури даних

dat.m <- structure(list(ave_max = c(15L, 6L), ave = c(6L, NA), lepo = c(4L, NA)), .Names = c("ave_max", "ave", "lepo"), class = "data.frame", row.names = c(NA, -2L))

Спроби

dat.m <- structure(list(ave_max = c(15L, 6L), ave = c(6L, NA), lepo = c(4L, NA)), .Names = c("ave_max", "ave", "lepo"), class = "data.frame", row.names = c(NA, -2L))

# ...
  1. Код і вихідні дані

    dat.m <- setDT(dat.m)
    

    Неправильний результат

            ave_max      ave      lepo
    1:           15        6         4
    2:            6       NA        NA
    Classes ‘data.table’ and "data.frame":  2 obs. of  3 variables:
    $ ave_max: int  15 6
    $ ave    : int  6 NA
    $ lepo   : int  4 NA
    - attr(*, ".internal.selfref")=<externalptr>
    
  2. Код і вихідні дані

    dat.m <- as.matrix(dcast(melt(setDT(dat.m), measure.vars = names(dat.m)), variable ~ rowid(variable))[, variable := NULL]);
    dimnames(dat.m) <- list(names(dat.m), NULL);
    

    Неправильний результат

     Error in `:=`(variable, NULL) :
    Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways.
    See help(":=").
    

R: 3.4.0 (бекпорти)
ОС: Debian 8.7.

Відповіді:

1 для відповіді № 1

Оператор відредагував його запитання та надає дані як data.frame:

dat.df <- structure(list(ave_max = c(15L, 6L), ave = c(6L, NA), lepo = c(4L, NA)),
.Names = c("ave_max", "ave", "lepo"), class = "data.frame",
row.names = c(NA, -2L))

dat.df
#  ave_max ave lepo
#1      15   6    4
#2       6  NA   NA
class(dat.df)
#[1] "data.frame"

Зараз він просить перетворити цей data.frame в матрицю, подібну до тієї, яка використовується як вхідні дані в ця відповідь.

Це можна досягти, використовуючи data.table:

library(data.table)   # CRAN version 1.10.4 used
# transpose the input data frame, use rowid() to create columns,
# remove a character column to ensure matrix will be of type integer,
# finally, coerce to matrix
dat.m2 <- as.matrix(
data.table::dcast(
data.table::melt(setDT(dat.df), measure.vars = names(dat.df)),
variable ~ rowid(variable)
)[, variable := NULL]
)
# add row names, remove column names
dimnames(dat.m2) <- list(names(dat.df), NULL)

dat.m2
#        [,1] [,2]
#ave_max   15    6
#ave        6   NA
#lepo       4   NA

str(dat.m2)
# int [1:3, 1:2] 15 6 4 6 NA NA
# - attr(*, "dimnames")=List of 2
#  ..$ : chr [1:3] "ave_max" "ave" "lepo"
#  ..$ : NULL

class(dat.m2)
#[1] "matrix"

Редагувати: Я вніс зміни до вищезазначеного коду, щоб використовувати оператор подвійної двокрапки, щоб явно вказати простір імен, з якого melt() і dcast() слід взяти. Зазвичай це не буде необхідним, оскільки data.table вже завантажено. Однак OP повідомляє про проблеми, які можуть бути спричинені пакетом reshape2 завантажується після data.table. The data.table пакет має власні швидші реалізації reshape2::dcast() і reshape2::melt(). Коли обидва пакунки з якихось причин завантажені, можуть статися зіткнення імен.


1 для відповіді № 2

OP надав дані як матрицю:

dat.m <- structure(c(150L, 60L, 41L, 61L, 0L, 0L), .Dim = c(3L, 2L), .Dimnames = list(
c("ave_max", "ave", "lepo"), NULL))

#    dat.m
#        [,1] [,2]
#ave_max  150   61
#ave       60    0
#lepo      41    0
class(dat.m)
#[1] "matrix"

Для цього набору даних OP хоче використовувати ggplot2 створити гістограму зі стовпчиками помилок, де висота стовпчиків задається значеннями ave а нижня і верхня межі стовпчиків помилок - lepo і ave_max, відповідно, у кожному стовпці.

Як ggplot2 очікує, що дані будуть подані як data.frame дані повинні бути перетворені. Для цього, data.table використовується:

library(data.table)   # CRAN version 1.10.4 used

# convert to data.table & transpose
transposed <- dcast(melt(as.data.table(dat.m, keep.rownames = "Vars"),
id.vars = "Vars"), variable ~ ...)
setnames(transposed, "variable", "Vars")

library(ggplot2)
ggplot(transposed, aes(x = Vars, y = ave, ymin = lepo, ymax = ave_max)) +
geom_col() +
geom_errorbar(width = .25)