代码之家  ›  专栏  ›  技术社区  ›  Ankhnesmerira

列出data.frames的列表列并选择唯一值

  •  2
  • Ankhnesmerira  · 技术社区  · 7 年前

    我有一个data.table'dt',其中有一个列('col2'),它是一个数据帧列表:

    require(data.table)
    DT <- data.table(col1 = c('A','A','B'),
                     col2 = list(data.frame(colA = c(1,3,54, 23), 
                                            colB = c("aa", "bb", "cc", "hh")),
                                 data.frame(colA =c(23, 1),
                                           colB = c("hh", "aa")), 
                                 data.frame(colA = 1,
                                           colB = "aa")))
    
    > DT
       col1         col2
    1:    A <data.frame>
    2:    A <data.frame>
    3:    B <data.frame>
    
    >> DT$col2
    [[1]]
      colA colB
    1    1   aa
    2    3   bb
    3   54   cc
    4   23   hh
    
    [[2]]
      colA colB
    1   23   hh
    2    1   aa
    
    [[3]]
      colA colB
    1    1   aa
    

    col2中的每个data.frame都有两列cola和colb。 我想要一个data.table输出来绑定每个 独特的 这些数据的行。帧基于dt的col1。 我想这就像用 rbindlist 在data.table的聚合函数中。

    这是所需的输出:

    > #desired output
    > output
       colA colB col1
    1:    1   aa    A
    2:    3   bb    A
    3:   54   cc    A
    4:   23   hh    A
    5:    1   aa    B
    

    dt第二行的数据帧( DT[2, col2] )具有重复项,并且每个唯一col1只需要唯一项。

    我试了一下,结果出错了。

    desired_output <- DT[, lapply(col2, function(x) unique(rbindlist(x))), by = col1]
    # Error in rbindlist(x) : 
    #   Item 1 of list input is not a data.frame, data.table or list
    

    这是“有效的”,尽管不是期望的输出:

    unique(rbindlist(DT$col2))
       colA colB
    1:    1   aa
    2:    3   bb
    3:   54   cc
    4:   23   hh
    

    有什么用的吗 滚动列表 在data.table的聚合函数中?

    4 回复  |  直到 7 年前
        1
  •  5
  •   Henrik plannapus    7 年前

    集团 by “col1”,运行 rbindlist 在“col2”上:

    unique(DT[ , rbindlist(col2), by = col1]) # trimmed thanks to @snoram
    #    col1 colA colB
    # 1:    A    1   aa
    # 2:    A    3   bb
    # 3:    A   54   cc
    # 4:    A   23   hh
    # 5:    B    1   aa
    
        2
  •  2
  •   Frank    7 年前

    每个唯一项只需要唯一项 col1

    如果为添加列 列1 ,上面的表达式表示“唯一条目”(列上无条件)。

    亨里克的回答是 列1 是的。另一个是:

    unique(DT[, rbindlist(setNames(col2, col1), id="col1")])
    

    我想这应该比

    bycols = "col1"
    unique(DT[, rbindlist(col2), by=bycols])   # Henrik's
    

    尽管扩展到(1) 列1 不是字符列(因此适合 setNames )或(2)有多个 by= 柱子不是那么明显。不管是哪种情况,我都会 .id 列等于行数 DT 然后复制过来:

    bycols = "col1"
    res = unique(DT[, rbindlist(col2, id="DT_row")])
    res[, (bycols) := DT[DT_row, ..bycols]]
    

    我想把那些列放在第一位/最左边 setcolorder(res, bycols) 应该可以,但我使用的data.table版本太旧,无法看到它这样做。

    还有 an open issue 为了一个 tidyr::unnest 类函数。

        3
  •  1
  •   Rohit    7 年前

    这是有效的:

    DT1<-apply(DT, 1, function(x){cbind(col1=x$col1,x$col2)})
    unique(rbindlist(DT1))
    #   col1 colA colB
    #1:    A    1   aa
    #2:    A    3   bb
    #3:    A   54   cc
    #4:    A   23   hh
    #5:    B    1   aa
    
        4
  •  1
  •   s_baldur    7 年前

    你可以这样做:

    nDT <- cbind(rbindlist(DT[[2]]), col1 = rep(DT[[1]], sapply(DT[[2]], nrow)))
    nDT[!duplicated(nDT)]
       colA colB col1
    1:    1   aa    A
    2:    3   bb    A
    3:   54   cc    A
    4:   23   hh    A
    5:    1   aa    B
    

    或者使用tidyr(受pkumar评论的启发):

    unique(tidyr::unnest(DT))
    

    或更通用的基r:

    names(DT[[2]]) <- DT[[1]]
    ndf <- do.call(rbind, DT[[2]])
    ndf$col1 <- substr(row.names(ndf), 1, 1)
    unique(ndf)
    
    推荐文章