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

如何创建将不同筛选器应用于数据帧的循环

r
  •  0
  • neuron  · 技术社区  · 6 年前

    我提前道歉,我的问题标题可能无法准确描述我要做的事情。我认为我需要创建的是一个循环,但我会给出更多细节。我有两个数据帧

    DF1

    chr location gene sample1 sample2 
    1 12345 FAM1 0.1 0
    1 124353 ABCA 1 0.5
    2 12353 ALMS1 2 0.1
    3 23456 TNN 0 0
    7 657864 MYBC3 0.3 1
    

    和DF2

    sucrose fructose glucose galactose
    FAM1 FAM2 ALMS1 ALMS2
    FAM2 TNN2 MYBC3 ABCA
    FAM3 MYBC2 TNN ABCA2
    FAM4 MYBC ABCA2 FAM3
    FAM5 ALMS2 ABCA3 FAM4
    

    因此,df1是我的主要数据帧,而df2包含我用来过滤df1的列。例如,我将使用df2(蔗糖)的第一列,并过滤df1以获取蔗糖列中的任何基因。因此,在应用了过滤器之后,数据看起来是这样的。

    chr location gene sample1 sample2 
    1 12345 FAM1 0.1 0
    

    所以我可以这样做,但是真正的df2有数千列。所以我想做的是如何创建一个循环?(如果这是正确的术语)运行在df2的所有列中,将它们作为过滤器应用到df1,然后将结果保存为新的数据帧。理想情况下,我希望新的数据框架与筛选它的列具有相同的名称,因此在我给出的示例中,新的数据框架将如下所示

    sucrose
    #   chr location gene sample1 sample2
    # 1   1    12345  FAM1   0.1       0  
    

    下面是一个脚本示例,我只为df2中的一列运行该脚本

    sucrose <- df1 %>%
      filter(gene %in% df2[[1]]) %>%
      filter(gene != "")
    
    sucrose$Number.of.MMVD.dogs <- (sucrose$sample1 + sucrose$sample2)
    
    sucrose <- sucrose  %>%
      filter(Number.of.MMVD.dogs >= 0.01)
    

    这个过滤器给我以下输出

    sucrose
    #   chr location gene sample1 sample2 Number.of.MMVD.dogs
    # 1   1    12345  FAM1   0.1       0        0.1
    

    我只是不想为我用来过滤df1的每一列都输入这个。我知道有一种更好的方法可以做到这一点,而不是用手,但我不确定如何做到这一点。我承认,它将创建大量的数据框架,但我将把它们保存到一个项目中。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Parfait    6 年前

    考虑改变宽度 DF2 转换为长格式 tidyr::gather 然后使用加入 dplyr::inner_join 具有 DF1 . 最后, split 新的数据帧 返回的列 许多数据帧的列表,理想情况下,这些数据帧在全球环境中的管理能力超过1000个:

    longdf <- df2 %>%
      tidyr::gather(sugar, gene)
    
    df1 <- df1 %>%
      dplyr::inner_join(longdf, by="gene")
    
    df_list <- split(df1, df1$sugar)
    
    # LIST OF THREE DATA FRAMES
    df_list
    # $galactose
    #   chr location gene sample1 sample2     sugar
    # 2   1   124353 ABCA       1     0.5 galactose
    
    # $glucose
    #   chr location  gene sample1 sample2   sugar
    # 3   2    12353 ALMS1     2.0     0.1 glucose
    # 4   3    23456   TNN     0.0     0.0 glucose
    # 5   7   657864 MYBC3     0.3     1.0 glucose
    
    # $sucrose
    #   chr location gene sample1 sample2   sugar
    # 1   1    12345 FAM1     0.1       0 sucrose
    

    如果数据帧存储在命名列表中,而不是作为单独的对象存储,则不会失去数据帧的任何功能:

    summary(df_list$galactose)
    #       chr       location          gene              sample1     sample2       sugar          
    #  Min.   :1   Min.   :124353   Length:1           Min.   :1   Min.   :0.5   Length:1          
    #  1st Qu.:1   1st Qu.:124353   Class :character   1st Qu.:1   1st Qu.:0.5   Class :character  
    #  Median :1   Median :124353   Mode  :character   Median :1   Median :0.5   Mode  :character  
    #  Mean   :1   Mean   :124353                      Mean   :1   Mean   :0.5                     
    #  3rd Qu.:1   3rd Qu.:124353                      3rd Qu.:1   3rd Qu.:0.5                     
    #  Max.   :1   Max.   :124353                      Max.   :1   Max.   :0.5            
    
    str(df_list$glucose)
    # 'data.frame': 3 obs. of  6 variables:
    #  $ chr     : int  2 3 7
    #  $ location: int  12353 23456 657864
    #  $ gene    : chr  "ALMS1" "TNN" "MYBC3"
    #  $ sample1 : num  2 0 0.3
    #  $ sample2 : num  0.1 0 1
    #  $ sugar   : chr  "glucose" "glucose" "glucose"
    
    head(df_list$sucrose)
    #   chr location gene sample1 sample2   sugar
    # 1   1    12345 FAM1     0.1       0 sucrose
    
        2
  •  0
  •   Elio Diaz    6 年前

    使用

    library(foreach)
    library(dplyr)
    
    
    df1 <- tribble(~chr, ~location, ~gene, ~sample1, ~sample2,
    1, 12345, "FAM1", 0.1, 0,
    1, 124353, "ABCA", 1, 0.5,
    2,12353, "ALMS1", 2, 0.1,
    3, 23456, "TNN", 0, 0,
    7, 657864, "MYBC3", 0.3 ,1)
    
    df2 <- tribble(
      ~sucrose, ~fructose,~ glucose,~ galactose,
      "FAM1","FAM2", "ALMS1", "ALMS2",
      "FAM2", "TNN2", "MYBC3", "ABCA",
      "FAM3", "MYBC2", "TNN" ,"ABCA2",
      "FAM4", "MYBC", "ABCA2", "FAM3",
      "FAM5", "ALMS2", "ABCA3", "FAM4"
    )
    
    foreach(i= 1:dim(df2)[2], .combine=rbind) %do% { 
    sucrose <- df1 %>%
      filter(gene %in% df2[[i]]) %>%
      filter(gene != "")
    sucrose$Number.of.MMVD.dogs <- (sucrose$sample1 + sucrose$sample2)
    sucrose <- sucrose  %>%
      filter(Number.of.MMVD.dogs >= 0.01)
    } -> your_variable
    

    输出为:

    # A tibble: 4 x 6
        chr location gene  sample1 sample2 Number.of.MMVD.dogs
      <dbl>    <dbl> <chr>   <dbl>   <dbl>               <dbl>
    1  1.00    12345 FAM1    0.100   0                   0.100
    2  2.00    12353 ALMS1   2.00    0.100               2.10 
    3  7.00   657864 MYBC3   0.300   1.00                1.30 
    4  1.00   124353 ABCA    1.00    0.500               1.50