如何在列表上使用Reforme2::melt时指定级别名称? 问题:

如何在列表上使用Reforme2::melt时指定级别名称? 问题:,r,list,reshape2,melt,R,List,Reshape2,Melt,我发现自己正在使用reformae2::melt从data.frame对象的分层列表中获取单个“长”的data.frame。但是,结果的列名具有标记为“L1”、“L2”等的列表层次结构级别。然而,由于这些级别具有意义,因此我希望为这些列指定有意义的名称。最好的方法是什么?可以使用对melt的单个调用来完成吗 我不喜欢熔化或重塑2,因此我愿意接受其他方法或方案 当前设置 假设我们有一个data.frame对象的分层列表,如下所示: library(reshape2) x <- structu

我发现自己正在使用
reformae2::melt
data.frame
对象的分层
列表中获取单个“长”的
data.frame
。但是,结果的列名具有标记为“L1”、“L2”等的列表层次结构级别。然而,由于这些级别具有意义,因此我希望为这些列指定有意义的名称。最好的方法是什么?可以使用对
melt
的单个调用来完成吗

我不喜欢
熔化
重塑2
,因此我愿意接受其他方法或方案

当前设置 假设我们有一个
data.frame
对象的分层列表,如下所示:

library(reshape2)
x <- structure(list(cyl_6 = structure(list(gear_3 = structure(list( mpg = 1:2, qsec = 3:4), .Names = c("mpg", "qsec"), row.names = c(NA, -2L), class = "data.frame"), gear_4 = structure(list(mpg = 5:6, qsec = 7:8), .Names = c("mpg", "qsec"), row.names = c(NA, -2L), class = "data.frame")), .Names = c("gear_3", "gear_4")), cyl_8 = structure(list(gear_3 = structure(list(mpg = 9:10, qsec = 11:12), .Names = c("mpg", "qsec"), row.names = c(NA, -2L), class = "data.frame"), gear_4 = structure(list(mpg = 13:14, qsec = 15:16), .Names = c("mpg", "qsec"), row.names = c(NA, -2L), class = "data.frame")), .Names = c("gear_3", "gear_4"    ))), .Names = c("cyl_6", "cyl_8"))
这是
头(mx)
的输出。我不想只说“L1”和“L2”:

因此,我求助于手动设置“L1”和“L2”:

names(mx)[3:4] <- c("gears", "cylinders")
你可以试试

library(tidyr)
res <- unnest(x, sex)
head(res)
#   sex  Hair   Eye value
#1 MALE Black Brown    32
#2 MALE Brown Brown    53
#3 MALE   Red Brown    10
#4 MALE Blond Brown     3
#5 MALE Black  Blue    11
#6 MALE Brown  Blue    50
这也适用于更多嵌套列表:

y <- list(x = x, y = x)
head(melt(y))
#   variable value     L3    L2 L1
# 1      mpg     1 gear_3 cyl_6  x
# 2      mpg     2 gear_3 cyl_6  x
# 3     qsec     3 gear_3 cyl_6  x
# 4     qsec     4 gear_3 cyl_6  x
# 5      mpg     5 gear_4 cyl_6  x
# 6      mpg     6 gear_4 cyl_6  x

那看起来会有用的。我在最初的问题中没有问过,但对于列表的层次结构来说,unnest会起作用吗?例如,
unnest(x、性别、地点、主题)
(假设列表结构是这样组织的)?我现在还不能测试它,因为我不能升级我的R以允许
tidyr
(我现在只能使用Ubuntu 14.04 LTS和R3.02)。@user29020我还没有这样测试过它。你能用类似的数据结构更新你的帖子吗。
1> head(mx)
   variable value  gears cylinders
1       mpg     1 gear_3     cyl_6
2       mpg     2 gear_3     cyl_6
3      qsec     3 gear_3     cyl_6
4      qsec     4 gear_3     cyl_6
5       mpg     5 gear_4     cyl_6
6       mpg     6 gear_4     cyl_6
library(tidyr)
res <- unnest(x, sex)
head(res)
#   sex  Hair   Eye value
#1 MALE Black Brown    32
#2 MALE Brown Brown    53
#3 MALE   Red Brown    10
#4 MALE Blond Brown     3
#5 MALE Black  Blue    11
#6 MALE Brown  Blue    50
library(dplyr)
dN <- unnest(lapply(x, unnest, gear), cylinders) %>%
                         gather(variable, value, mpg:qsec)
head(dN,3)
#  cylinders   gear variable value
#1     cyl_6 gear_3      mpg     1
#2     cyl_6 gear_3      mpg     2
#3     cyl_6 gear_4      mpg     5
library('reshape2')
x <- structure(list(cyl_6 = structure(list(gear_3 = structure(list( mpg = 1:2, qsec = 3:4), .Names = c("mpg", "qsec"), row.names = c(NA, -2L), class = "data.frame"), gear_4 = structure(list(mpg = 5:6, qsec = 7:8), .Names = c("mpg", "qsec"), row.names = c(NA, -2L), class = "data.frame")), .Names = c("gear_3", "gear_4")), cyl_8 = structure(list(gear_3 = structure(list(mpg = 9:10, qsec = 11:12), .Names = c("mpg", "qsec"), row.names = c(NA, -2L), class = "data.frame"), gear_4 = structure(list(mpg = 13:14, qsec = 15:16), .Names = c("mpg", "qsec"), row.names = c(NA, -2L), class = "data.frame")), .Names = c("gear_3", "gear_4"    ))), .Names = c("cyl_6", "cyl_8"))
reshape2:::melt.list
# function (data, ..., level = 1) 
# {
#   parts <- lapply(data, melt, level = level + 1, ...)
#   result <- rbind.fill(parts)
#   names <- names(data) %||% seq_along(data)
#   lengths <- vapply(parts, nrow, integer(1))
#   labels <- rep(names, lengths)
#   label_var <- attr(data, "varname") %||% paste("L", level, sep = "")
#   result[[label_var]] <- labels
#   result
# }
meltList <- function (data, ..., level = 1, nn) {
  require('reshape2')
  '%||%' <- function (a, b) if (!is.null(a)) a else b
  parts <- lapply(data, melt, level = level + 1, ...)
  result <- plyr::rbind.fill(parts)
  names <- names(data) %||% seq_along(data)
  lengths <- vapply(parts, nrow, integer(1))
  labels <- rep(names, lengths)
  label_var <- attr(data, "varname") %||% paste("L", level, sep = "")
  result[[label_var]] <- labels
  if (!missing(nn))
    names(result)[grep('^L\\d+', names(result))] <- nn
  result
}
head(meltList(x, nn = c('gears','cylinders')))
#   variable value  gears cylinders
# 1      mpg     1 gear_3     cyl_6
# 2      mpg     2 gear_3     cyl_6
# 3     qsec     3 gear_3     cyl_6
# 4     qsec     4 gear_3     cyl_6
# 5      mpg     5 gear_4     cyl_6
# 6      mpg     6 gear_4     cyl_6
y <- list(x = x, y = x)
head(melt(y))
#   variable value     L3    L2 L1
# 1      mpg     1 gear_3 cyl_6  x
# 2      mpg     2 gear_3 cyl_6  x
# 3     qsec     3 gear_3 cyl_6  x
# 4     qsec     4 gear_3 cyl_6  x
# 5      mpg     5 gear_4 cyl_6  x
# 6      mpg     6 gear_4 cyl_6  x
head(meltList(y, nn = c('gears','cylinders','variable')))
#   variable value  gears cylinders variable
# 1      mpg     1 gear_3     cyl_6        x
# 2      mpg     2 gear_3     cyl_6        x
# 3     qsec     3 gear_3     cyl_6        x
# 4     qsec     4 gear_3     cyl_6        x
# 5      mpg     5 gear_4     cyl_6        x
# 6      mpg     6 gear_4     cyl_6        x