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?
3 Réponses :
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
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
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. 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