将 data.frame 转换为列表列表的列表列表
Converting data.frame to a list of list of list of lists
我正在使用具有不同参数的不同模型。我将它们存储在数据库中很方便。当我拉出它们时,它们以 dataframe 的形式出现,我称之为 df
。
在 df
中有几列有助于区分每个参数,因此每一(整)行最终都是唯一的。
例如
col_1 <- c("model_1", "model_1", "model_1", "model_1", "model_2", "model_2", "model_2", "model_2")
col_2 <- c("category_1", "category_1", "category_2", "category_2", "category_1", "category_1", "category_2", "category_2")
col_3 <- c("type_1", "type_2", "type_1", "type_2", "type_1", "type_2", "type_1", "type_2")
col_4 <- c("name_1", "name_2", "name_3", "name_4", "name_5", "name_6", "name_7", "name_8")
col_5 <- c("value_1", "value_2", "value_3", "value_4", "value_5", "value_6", "value_7", "value_8")
mat <- matrix(c(col_1, col_2, col_3, col_4, col_5), ncol = 5)
df <- data.frame(mat)
names(df) <- c("model", "category", "type", "name", "value")
I would be interested in transforming df
into a list of list of list
... - call it deep_list
- so that each parameter value could be
accessed like
parameter <- deep_list$model_1$category_2$type_2$name_4
and it should give me value_4
.
我一直在阅读此线程 Converting a data.frame to a list of lists 并尝试充分利用 {plyr}
中的 dlply()
函数作为
not_deep_list <- dlply(df,1,c)
或
not_list <- df %>% group_by(model)
我认为这是一个非常类似的问题(因此具有类似的标题)。
但是它的不同之处在于它需要处理更多"layers"(即列)信息,因此deep_list
名称和标题...
欢迎任何建议(递归、循环、向量化解决方案,functions-from-packages-I-never-heard-of,...)
谢谢!
首先,我在您的 data.frame 中指定了 stringsAsFactors=FALSE
- 这很重要,因为我使用 split(...)
它将识别 因素水平 而不是比因子值。明白我的意思,运行
vec <- factor(c("apple"), levels=c("apple","banana"))
split(vec, vec)
# $apple
# [1] apple
# Levels: apple banana
# $banana
# factor(0)
# Levels: apple banana
好的 - 所以将字符串指定为非因素
df <- data.frame(mat, stringsAsFactors=FALSE)
试试这个自定义函数 - 它是递归的,如果 length(split(..., ...)) > 1)
调用自身 - 即,如果 data.frame 列的 split(...)
导致 > 1 组,该函数将使用新参数 i[,-1]
.
调用自身
recursive_split <- function(L) {
L1 <- split(L, L[,1])
if (length(L1) == 1) {
L2 <- lapply(L1, function(i) i[,-1])
return(L2)
} else {
lapply(L1, function(i) recursive_split(i[,-1]))
}
}
deep_list <- recursive_split(df)
# $model_1
# $model_1$category_1
# $model_1$category_1$type_1
# $model_1$category_1$type_1$name_1
# [1] "value_1"
# $model_1$category_1$type_2
# $model_1$category_1$type_2$name_2
# [1] "value_2"
# $model_1$category_2
# $model_1$category_2$type_1
# $model_1$category_2$type_1$name_3
# [1] "value_3"
# etc
deep_list$model_1$category_2$type_2$name_4
# [1] "value_4"
我正在使用具有不同参数的不同模型。我将它们存储在数据库中很方便。当我拉出它们时,它们以 dataframe 的形式出现,我称之为 df
。
在 df
中有几列有助于区分每个参数,因此每一(整)行最终都是唯一的。
例如
col_1 <- c("model_1", "model_1", "model_1", "model_1", "model_2", "model_2", "model_2", "model_2")
col_2 <- c("category_1", "category_1", "category_2", "category_2", "category_1", "category_1", "category_2", "category_2")
col_3 <- c("type_1", "type_2", "type_1", "type_2", "type_1", "type_2", "type_1", "type_2")
col_4 <- c("name_1", "name_2", "name_3", "name_4", "name_5", "name_6", "name_7", "name_8")
col_5 <- c("value_1", "value_2", "value_3", "value_4", "value_5", "value_6", "value_7", "value_8")
mat <- matrix(c(col_1, col_2, col_3, col_4, col_5), ncol = 5)
df <- data.frame(mat)
names(df) <- c("model", "category", "type", "name", "value")
I would be interested in transforming
df
into a list of list of list ... - call itdeep_list
- so that each parameter value could be accessed likeparameter <- deep_list$model_1$category_2$type_2$name_4
and it should give me
value_4
.
我一直在阅读此线程 Converting a data.frame to a list of lists 并尝试充分利用 {plyr}
中的 dlply()
函数作为
not_deep_list <- dlply(df,1,c)
或
not_list <- df %>% group_by(model)
我认为这是一个非常类似的问题(因此具有类似的标题)。
但是它的不同之处在于它需要处理更多"layers"(即列)信息,因此deep_list
名称和标题...
欢迎任何建议(递归、循环、向量化解决方案,functions-from-packages-I-never-heard-of,...)
谢谢!
首先,我在您的 data.frame 中指定了 stringsAsFactors=FALSE
- 这很重要,因为我使用 split(...)
它将识别 因素水平 而不是比因子值。明白我的意思,运行
vec <- factor(c("apple"), levels=c("apple","banana"))
split(vec, vec)
# $apple
# [1] apple
# Levels: apple banana
# $banana
# factor(0)
# Levels: apple banana
好的 - 所以将字符串指定为非因素
df <- data.frame(mat, stringsAsFactors=FALSE)
试试这个自定义函数 - 它是递归的,如果 length(split(..., ...)) > 1)
调用自身 - 即,如果 data.frame 列的 split(...)
导致 > 1 组,该函数将使用新参数 i[,-1]
.
recursive_split <- function(L) {
L1 <- split(L, L[,1])
if (length(L1) == 1) {
L2 <- lapply(L1, function(i) i[,-1])
return(L2)
} else {
lapply(L1, function(i) recursive_split(i[,-1]))
}
}
deep_list <- recursive_split(df)
# $model_1
# $model_1$category_1
# $model_1$category_1$type_1
# $model_1$category_1$type_1$name_1
# [1] "value_1"
# $model_1$category_1$type_2
# $model_1$category_1$type_2$name_2
# [1] "value_2"
# $model_1$category_2
# $model_1$category_2$type_1
# $model_1$category_2$type_1$name_3
# [1] "value_3"
# etc
deep_list$model_1$category_2$type_2$name_4
# [1] "value_4"