1
votes

Comment sélectionner le contenu de la colonne en fonction de la valeur maximale dans les groupes d'une autre colonne. Sélectionnez le nom du marqueur en fonction de la valeur maximale pour chaque gène

J'ai le df suivant:

aggregate(df$pval, by = list(df$Gene), which.max)

Je veux obtenir le nom du marqueur basé sur la pvalue maximale pour chaque gène. Ce que j'ai essayé:

peak_marker <-df[which.max(df[,2]),3]

Mais le résultat est le nom du marqueur avec la pvalue la plus élevée dans toute la trame de données et non le nom du marqueur avec le pval le plus élevé pour chaque gène. p>

J'ai aussi essayé ceci sans succès:

Gene pval  Marker
A      0.12     M1
A      0.11     M2
B      0.33     M3
B      0.55     M4
B      0.06     M5
D      0.03     M7
D      0.04     M8


0 commentaires

3 Réponses :


0
votes

Solution utilisant dplyr :

  df %>% 
    group_by(Gene) %>% 
    filter(val == max(val)) %>% 
    ungroup()

Retourne:

  # A tibble: 3 x 3
  # Groups:   Gene [3]
    Gene    val Marker
    <chr> <dbl> <chr> 
  1 A      0.12 M1    
  2 B      0.55 M4    
  3 D      0.04 M8   

Ou, si nous voulons nous débarrasser du groupement:

library(dplyr)
df %>% 
  group_by(Gene) %>% 
  filter(val == max(val))


0 commentaires

0
votes

Voici des solutions utilisant à la fois base et data.table !

Lecture des données:

setDT(df)
df[,.SD[order(-pval)][1,Marker], by = Gene]
#>    Gene V1
#> 1:    A M1
#> 2:    B M4
#> 3:    D M8

Avec base , nous allons essentiellement passer en revue chaque valeur unique pour Gene et sous-ensemble manuellement les données

sapply(unique(df[,'Gene']), FUN = function(g) {
    d = df[df$Gene == g,]
    d[which.max(d[,2]),3]
})
#>    A    B    D 
#> "M1" "M4" "M8"

Avec data.table , nous pouvons utiliser l'argument by pour diviser les données en groupes, puis accéder à la partie des données au sein du groupe en utilisant .SD code > (qui est un sous-ensemble des données)

library(data.table)
df = fread("Gene pval  Marker
A      0.12     M1
A      0.11     M2
B      0.33     M3
B      0.55     M4
B      0.06     M5
D      0.03     M7
D      0.04     M8")
setDF(df)


0 commentaires

0
votes

En fait, vous êtes très proche de le faire avec agrégat , mais vous avez peut-être besoin d'une aide supplémentaire de merge .

Voici une solution de base R, où agrégat + merge ont été utilisés, c'est-à-dire

df <- structure(list(Gene = c("A", "A", "B", "B", "B", "D", "D"), pval = c(0.12, 
0.11, 0.33, 0.55, 0.06, 0.03, 0.04), Marker = c("M1", "M2", "M3", 
"M4", "M5", "M7", "M8")), class = "data.frame", row.names = c(NA, 
-7L))

tels que

> dfout
  Gene pval Marker
1    A 0.12     M1
2    B 0.55     M4
3    D 0.04     M8

DATA

dfout <- merge(aggregate(pval~Gene,df,max),df,all.x = T)


0 commentaires