将具有不同向量长度(压缩行存储)的列表转换为R中的sparseMatrix

将具有不同向量长度(压缩行存储)的列表转换为R中的sparseMatrix,r,sparse-matrix,reshape,R,Sparse Matrix,Reshape,我使用MariaDB表来存储我的稀疏数据。 当我将其导入R时,我得到以下db\u帧数据帧: db_frame <- dbGetQuery(mydb, "SELECT uid, column_json(groups) FROM matrix") db_frame uid column_json(groups) 1 8 {"33755311":1,"58534882":1} 2 9

我使用MariaDB表来存储我的稀疏数据。 当我将其导入R时,我得到以下
db\u帧
数据帧:

db_frame <- dbGetQuery(mydb, "SELECT uid, column_json(groups) FROM matrix")
db_frame
  uid                      column_json(groups)
1   8              {"33755311":1,"58534882":1}
2   9                           {"75338985":1}
3  15               {"5445504":1,"58534882":1}
4  16 {"14897324":1,"22522055":1,"68471405":1}
5  20              {"22522055":1,"48940689":1}
我用两种方法来做这件事,但在我看来,这两种方法都非常低效。 在现实生活中,变量(列)的数量约为2-3K,观察值(行)的数量约为100万。因此,我的两种方法都需要很长的时间来完成这项工作(天)

有没有其他更优雅的方式来进行这种转换? 提前谢谢你

UPD:有指向两个R格式数据帧的链接:

  • -来自示例5观察的数据帧
  • -速度测试用10K观测值的真实数据帧
  • UPD2:
    核心i3 2.93 Ghz

    变量和观察值名称列表:

    groups <- sort(unique(unlist(var_list_names)))
    groups
    [1] "14897324" "22522055" "33755311" "48940689" "5445504"  "58534882" "68471405" "75338985"
    uids <- db_frame$uid
    uids
    [1] "8"  "9"  "15" "16" "20"
    

    groups我认为这会起作用,但由于我没有测试数据,不确定它的效率如何

    library(data.table)
    library(magrittr)
    split(df, seq(nrow(df))) %>% 
      lapply(function(x) {
        dt <- data.table(t(unlist(fromJSON(x$column_json))))
        dt[, id := x$uid]
      }) %>% 
      rbindlist(fill = TRUE)
    
    库(data.table)
    图书馆(magrittr)
    拆分(df,seq(nrow(df)))%>%
    lappy(函数(x){
    dt%
    rbindlist(fill=TRUE)
    
    感谢您让我从
    data.table
    软件包中找到
    rbindlist
    函数。
    我稍微简化了他的代码,并添加了稀疏格式的转换。
    测试10K观测的转换时间令人印象深刻6秒

    --------------方法4使用“rbindlist”

    库(RMySQL)
    图书馆(矩阵)
    图书馆(rjson)
    库(数据表)
    图书馆(magrittr)
    
    df谢谢!关闭,但不完全是必需的。我已经上传了源数据帧。您可以自己检查结果。还有其他问题-如何将其转换为稀疏格式?最好是在开始时,因为占用大量内存。您还可以在比较表中检查代码效率。(参见UPD2)很高兴我提供了帮助(尽管这不是你真正需要的):)
    library("rjson")
    var_list <- lapply(db_frame[,-1],fromJSON)
    var_list_names <- lapply(var_list,names)
    var_list_names
    [[1]]
    [1] "33755311" "58534882"
    
    [[2]]
    [1] "75338985"
    
    [[3]]
    [1] "5445504"  "58534882"
    
    [[4]]
    [1] "14897324" "22522055" "68471405"
    
    [[5]]
    [1] "22522055" "48940689"
    
    groups <- sort(unique(unlist(var_list_names)))
    groups
    [1] "14897324" "22522055" "33755311" "48940689" "5445504"  "58534882" "68471405" "75338985"
    uids <- db_frame$uid
    uids
    [1] "8"  "9"  "15" "16" "20"
    
    row_number = length(uids)
    col_number = length(groups)
    
    # creating empty sparse matrix M1
    M1 <- sparseMatrix(dims = c(row_number,col_number), i={}, j={}, x=1)
    rownames(M1) <- uids
    colnames(M1) <- groups
    
    # filling M1
    for (i in 1:row_number) {
          M1[i,var_list_names[[i]]] <-1
    }
    M1
    
    library("reshape2")
    long <- melt(var_list)
    long
       value       L2 L1
    1      1 33755311  1
    2      1 58534882  1
    3      1 75338985  2
    4      1  5445504  3
    5      1 58534882  3
    6      1 14897324  4
    7      1 22522055  4
    8      1 68471405  4
    9      1 22522055  5
    10     1 48940689  5
    
    i=long$L1
    j=match(long[,"L2"],groups)
    
    M2 <-sparseMatrix(i=i, j=j, x=1)
    rownames(M2) <- uids
    colnames(M2) <- groups
    M2
    
    library(data.table)
    library(magrittr)
    split(df, seq(nrow(df))) %>% 
      lapply(function(x) {
        dt <- data.table(t(unlist(fromJSON(x$column_json))))
        dt[, id := x$uid]
      }) %>% 
      rbindlist(fill = TRUE)
    
    library(RMySQL)
    library(Matrix)
    library(rjson)
    library(data.table)
    library(magrittr)
    
    df <- dbGetQuery(mydb, "SELECT uid, column_json(groups) FROM matrix")    
    
    # "rbindlist" does all the work    
    M3 <- lapply(df[,-1],fromJSON) %>% rbindlist(fill=TRUE)
    
    # replace NA with 0 (required for sparsematrix type)
    M3[is.na(M3)] <- 0 
    # converting to sparsematrix type
    M3 <- as(as.matrix(M3), "sparseMatrix")
    
    # make some order :)
    M3 <- M3[, order(as.integer(colnames(M3)))]
    row.names(M3) <- df$uid