将data.frame转换为列表列表列表

时间:2018-05-09 18:47:11

标签: r list dplyr plyr

我正在使用所有具有不同参数的不同模型。我很方便将它们存储在数据库中。当我拉它们时,它们以 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")
  

我有兴趣将df转换为列表列表   ... - 将其称为deep_list - 以便每个参数值都可以   像

一样访问
parameter <- deep_list$model_1$category_2$type_2$name_4
     

它应该给我value_4

我一直在阅读此帖子Converting a data.frame to a list of lists并试图充分利用dlply()中的{plyr}函数

not_deep_list <- dlply(df,1,c)

not_list <- df %>% group_by(model)

我认为这是一个非常类似的问题(因此类似的标题)。

然而它在某种意义上是不同的,它需要处理更多信息的“层”(即列),因此deep_list名称和标题......

欢迎任何建议(递归,循环,矢量化解决方案,函数从包 - 我从来没有听说过,......)

谢谢!

1 个答案:

答案 0 :(得分:4)

首先,我在您的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(...)导致&gt; 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"