【问题标题】:Using “combn” to create list of dataframes for all combinations of variables selected and columns for variables not selected使用“combn”为所选变量的所有组合和未选择变量的列创建数据框列表
【发布时间】:2021-05-04 16:57:31
【问题描述】:

从下面的 z 数据框中,我想生成一个新数据框列表,其中每个数据框都基于名称向量的 3 个不同值的唯一组合。在下面的数据框中,我在 Name 列中有 5 个不同的名称(它们有多个复制条目)。 3 的不同组合的数量为 10(在没有替换的情况下采样且顺序不重要)。 虽然选择基于名称向量,但我希望新数据框包含其他信息列。在这种情况下,投票列。我还希望除了这两列之外,每个数据框还包含两个附加列,其中包含未选择的行。例如,如果您在 combdf 中的第一个数据框下方运行代码,将包含 John、Lee、Susan 和他们的投票。但是我无法找到/弄清楚如何为该数据框添加其余两个名称及其投票的两列,其余的则依此类推。这两列的行数会更少,所以我对缺失单元格的 NA 很好。

Name <- c("Jhon", "Lee", "Suzan", "Abhinav",
      "Brain")
Vote <- letters[1:21]
z <- as.data.frame (cbind(Name, Vote))
comb<-combn(unique(as.character(z$Name)), 3)
combdf <- apply(comb, 2, function(vec) z[ z$Name %in% vec, ] )

【问题讨论】:

    标签: r combinations


    【解决方案1】:

    一个更简单的选择是使用bind_rowsfiltered 在“名称”中具有“vec”和第二个没有这些的数据,重命名它以便它创建填充有NA 的新列

    library(dplyr)
    out <- z %>%
              pull(Name) %>%
              unique %>%
             combn(., 3, FUN = function(vec) 
              z %>%
               filter(Name %in% vec) %>%
               bind_rows(z %>% 
                       filter(!Name %in% vec) %>% 
                       rename(Name2 = Name, Vote2 = Vote)), simplify = FALSE)
    

    -输出

    out[[1]]
    #    Name Vote   Name2 Vote2
    #1   Jhon    a    <NA>  <NA>
    #2    Lee    b    <NA>  <NA>
    #3  Suzan    c    <NA>  <NA>
    #4   Jhon    f    <NA>  <NA>
    #5    Lee    g    <NA>  <NA>
    #6  Suzan    h    <NA>  <NA>
    #7   Jhon    k    <NA>  <NA>
    #8    Lee    l    <NA>  <NA>
    #9  Suzan    m    <NA>  <NA>
    #10  Jhon    p    <NA>  <NA>
    #11   Lee    q    <NA>  <NA>
    #12 Suzan    r    <NA>  <NA>
    #13  Jhon    u    <NA>  <NA>
    #14  <NA> <NA> Abhinav     d
    #15  <NA> <NA>   Brain     e
    #16  <NA> <NA> Abhinav     i
    #17  <NA> <NA>   Brain     j
    #18  <NA> <NA> Abhinav     n
    #19  <NA> <NA>   Brain     o
    #20  <NA> <NA> Abhinav     s
    #21  <NA> <NA>   Brain     t
    

    另外,如果我们需要在底部有NA

    out2 <- z %>%
              pull(Name) %>%
              unique %>%
             combn(., 3, FUN = function(vec) 
              z %>%
               filter(Name %in% vec) %>%
               bind_rows(z %>% 
                       filter(!Name %in% vec) %>% 
                       rename(Name2 = Name, Vote2 = Vote)) %>%
               mutate(across(c(Name2, Vote2),
                 ~ .[order(is.na(.))])), simplify = FALSE)
    
    
    
    out2[[1]]
    #    Name Vote   Name2 Vote2
    #1   Jhon    a Abhinav     d
    #2    Lee    b   Brain     e
    #3  Suzan    c Abhinav     i
    #4   Jhon    f   Brain     j
    #5    Lee    g Abhinav     n
    #6  Suzan    h   Brain     o
    #7   Jhon    k Abhinav     s
    #8    Lee    l   Brain     t
    #9  Suzan    m    <NA>  <NA>
    #10  Jhon    p    <NA>  <NA>
    #11   Lee    q    <NA>  <NA>
    #12 Suzan    r    <NA>  <NA>
    #13  Jhon    u    <NA>  <NA>
    #14  <NA> <NA>    <NA>  <NA>
    #15  <NA> <NA>    <NA>  <NA>
    #16  <NA> <NA>    <NA>  <NA>
    #17  <NA> <NA>    <NA>  <NA>
    #18  <NA> <NA>    <NA>  <NA>
    #19  <NA> <NA>    <NA>  <NA>
    #20  <NA> <NA>    <NA>  <NA>
    #21  <NA> <NA>    <NA>  <NA>
    

    或者也可以使用setdiff/anti_join from dplyr

    out <- z %>% 
       pull(Name) %>% 
       unique %>% 
       combn(., 3, FUN = function(vec) {
                 z1 <- z %>%
                           filter(Name %in% vec)
                 z2 <- setdiff(z, z1)
                 names(z2) <- paste0(names(z2), 2)
                 bind_rows(z1, z2)
                 }, simplify = FALSE)
    

    【讨论】:

      【解决方案2】:
      f <- function(df,n)
      { # creates n NA rows
        naDF = df[1,]
        naDF[1,] <- NA
        naDF[rep(seq_len(nrow(naDF)), each = n), ]
      }
      # previous code unchanged
      
      df <- lapply(1:dim(comb)[2], function(x) {df1 = z[ z$Name %in% comb[,x], ]; df2 = z[ !z$Name %in% comb[,x], ]; cbind(df1, rbind(df2, f(df2, nrow(df1)-nrow(df2))))})
      
      > df[[1]]
          Name Vote    Name Vote
      1   Jhon    a Abhinav    d
      2    Lee    b   Brain    e
      3  Suzan    c Abhinav    i
      6   Jhon    f   Brain    j
      7    Lee    g Abhinav    n
      8  Suzan    h   Brain    o
      11  Jhon    k Abhinav    s
      12   Lee    l   Brain    t
      13 Suzan    m    <NA> <NA>
      16  Jhon    p    <NA> <NA>
      17   Lee    q    <NA> <NA>
      18 Suzan    r    <NA> <NA>
      21  Jhon    u    <NA> <NA>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-05
        • 2020-06-20
        相关资源
        最近更新 更多