1
votes

Diviser un data.frame, trier et sous-ensemble à partir d'une liste de data.frames

J'ai un grand data.frame qui ressemble à ceci:

>       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

Je voudrais diviser le bloc de données toutes les 3 colonnes, par exemple Statistic1, fdr1 et Value1. Ensuite, triez chaque data.frame fractionné par colonne Statistic * dans l'ordre décroissant et prenez les 20 premiers noms de ligne de chaque data.frames triés correspondant à l'étiquette Signif dans la colonne Value * du data.frame trié.

Sortie souhaitée

   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

De chaque data.frame, je prendrai les 20 premiers noms de ligne.

Quelqu'un peut-il m'aider s'il vous plaît?

r

0 commentaires

3 Réponses :


3
votes

Vous pouvez diviser le bloc de données en utilisant split.default . Parcourez la liste et effectuez les actions requises. Traduire vos exigences donnerait,

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,]})

Cependant, notez que puisque votre exemple ne comporte que 3 lignes, alors faire la dernière condition ( 1:20 ) entraînera NA lignes


0 commentaires

1
votes

Voici une autre solution de base, basée sur ces réponses , il va diviser l'ensemble de données toutes les trois colonnes, sans voir les noms:

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)

Avec de fausses données:

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


0 commentaires

0
votes

tidyverse réponse en utilisant la base R split.default nous divisons toutes les 3 colonnes, arrangez selon la 1ère colonne, filtre code> valeurs de la 3ème colonne et enfin sélectionner les lignes.

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

Pour cet exemple, il s'agit de sélectionner seulement 2 lignes, pour vos données réelles, vous pouvez changer 2 à 20 pour obtenir les 20 premières lignes.


0 commentaires