从data.frame列表中拆分data.frame,排序和子集

时间:2019-04-24 06:59:33

标签: r

我有一个看起来像这样的大data.frame:

   Statistic1    fdr1     Value1   Statistic2  fdr2   Value2
       2        0.0001    Signif      1.8      0.001   Signif 
      0.3        0.13       0          5        0.5      0
      1.5        0.01     Signif      0.4      0.009   Signif

我想每3列拆分一次数据帧,例如Statistic1,fdr1和Value1。然后按Statistic *列按降序对每个拆分的data.frame进行排序,并获取与Value *列中的Signif标签对应的每个已排序data.frames的前20行名称。 排序后的data.frame。

所需的输出

>       df1         

>        Statistic1    fdr1     Value1   
>            2        0.0001    Signif            
>           1.5        0.01     Signif     

>        Statistic2    fdr2     Value2
>           1.8        0.001    Signif 
>           0.4        0.009    Signif

从每个单个data.frame中,我将获取前20行名称。

有人可以帮我吗?

3 个答案:

答案 0 :(得分:3)

您可以使用split.default分割数据帧。遍历列表并执行所需的操作。翻译您的要求会给您

lapply(split.default(df, gsub('\\D+', '', names(df))), function(i) 
                                                {i <- i[i[3] != 0,];
                                                 i <- i[order(i[1], decreasing = TRUE),]; 
                                                 i[1:20,]})

但是,请注意,由于您的示例只有3行,因此执行最后一个条件(1:20)将导致NA

答案 1 :(得分:1)

这是基于this answers的另一个基本解决方案,它将数据集每三列拆分一次,而不会看到名称:

lapply(seq(1, ncol(df), by=3), function(i) {
                                           i <- df[i: pmin((i+2), ncol(df))]
                                           i <- i[order(i[1], decreasing = TRUE),]
                                           head(i,2)  # put 2 to see the results, you need 20
                                           })

[[1]]
  Statistic1  fdr1 Value1
1        2.0 0.001 Signif
3        1.5 0.010 Signif

[[2]]
  Statistic2  fdr2 Value2
2        5.0 0.500      0
1        1.8 0.001 Signif

使用伪造数据:

df <- data.frame(Statistic1  = c(2, 0.3, 1.5),
                 fdr1 = c(0.001, 0.13, 0.01),
                 Value1 = c("Signif",0,"Signif"),
                 Statistic2  = c(1.8,5,0.4),
                 fdr2 = c(0.001, 0.5, 0.009),
                 Value2 = c("Signif",0,"Signif"),
                 stringsAsFactors = FALSE)

答案 2 :(得分:0)

tidyverse使用基数R split.default的答案,我们每隔3列进行拆分,根据第一列拆分arrange,从第三列拆分filter值,最后选择行。

library(tidyverse)

map(split.default(df, gl(ncol(df)/3, 3)), 
    . %>% arrange_at(1) %>% 
          filter_at(3, ~. != 0) %>%
          slice(n() : (n()- 2)))


#$`1`
#  Statistic1   fdr1 Value1
#1        2.0 0.0001 Signif
#2        1.5 0.0100 Signif

#$`2`
#  Statistic2  fdr2 Value2
#1        1.8 0.001 Signif
#2        0.4 0.009 Signif

在此示例中,仅选择2行,对于实际数据,您可以将2更改为20以获取前20行。