2012-01-03 2 views
2

J'espère que cette question n'est pas trop simple pour ce forum.data.frame tranchage

J'ai créé un data.frame df:

 CAS  Name  CID 
89 13010-47-4 Lomustine   3950 
90 130209-82-4 Latanoprost  5311221,5282380,46705340,3890 
91 130636-43-0 Nifekalant  268083 
92 130929-57-6 Entacapone  5281081 

et un vecteur VEC

[1] 5282380 18471829 45923789 44308022 44266812 24883465 24867475 24867460 

Je voudrais extraire les lignes de df qui contient un certain nombre de VEC. J'ai essayé de résoudre ce problème par ce code:

df$GC[(df$CID %in% vec)] = 1 

df[df$GC==1,] 

Mais le problème avec cette solution est que je ne reçois que les lignes qui ne contiennent qu'un seul numéro dans la colonne CID. Les lignes qui contiennent plusieurs valeurs dans CID comme la ligne 90 n'apparaissent pas.

Existe-t-il une solution élégante à ce problème?

Merci à l'avance

Répondre

4

Compte tenu de votre commentaire sur Je pensais faire une suggestion de réponse Edi (ce qui me plaît). La compression de valeurs séparées par des virgules dans une seule colonne d'une trame de données est maladroite et (selon mon expérience) ne fait que conduire à la frustration. Je trouve souvent plus simple de le garder dans une structure de données séparée, une liste:

dat <- read.table(text = "  CAS  Name  CID 
    13010-47-4 Lomustine   3950 
    130209-82-4 Latanoprost  5311221,5282380,46705340,3890 
    130636-43-0 Nifekalant  268083 
    130929-57-6 Entacapone  5281081",sep = "",header = TRUE) 

cid <- sapply(dat$CID,strsplit,",",USE.NAMES = FALSE) 

Sous cette forme, les choses sont souvent plus faciles à travailler avec:

ID <- c(5282380, 18471829, 45923789, 44308022, 44266812, 24883465, 24867475, 24867460, 3950) 
dat[sapply(cid,function(x) {any(x %in% as.character(ID))}),] 
      CAS  Name       CID 
1 13010-47-4 Lomustine       3950 
2 130209-82-4 Latanoprost 5311221,5282380,46705340,3890 

Vous pouvez toujours utiliser rownames dans dat et les noms de la liste pour garder chaque article droit, si vous vous inquiétez des changements de commandes.

(Notez également que ma fonction anonyme est en supposant que ID sera finalement trouvé par les règles de détermination de la portée de R, vous pouvez modifier la fonction de passer ID explicitement si vous le souhaitez.)

+0

Merci pour l'indice. Travailler avec les valeurs séparées par des virgules de sqeezing est vraiment frustrant :) –

4

Une façon est d'utiliser grep():

> txt <- "  CAS  Name  CID 
+ 13010-47-4 Lomustine   3950 
+ 130209-82-4 Latanoprost  5311221,5282380,46705340,3890 
+ 130636-43-0 Nifekalant  268083 
+ 130929-57-6 Entacapone  5281081 
+ " 
> con <- textConnection(txt) 
> df <- read.table(con, header = TRUE) 
> close(con) 
> ID <- c(5282380, 18471829, 45923789, 44308022, 44266812, 24883465, 24867475, 24867460, 3950) 
> grep(paste("\\b", ID, "\\b", sep="", collapse = "|"), dat$CID) 
[1] 1 2 
+1

Nice. FYI, à partir de R-2.14, et grâce à R-core, vous pouvez lire les données textuelles dans une seule commande, 'txt <- read.table (text =" Corps de table ")', évitant l'ouverture explicite et fermeture des connexions. –

+0

@Josh: Merci! - Je ne savais pas ça. – EDi

+0

Merci pour votre réponse rapide. Le problème avec cette solution est, par exemple, que un ID "08" trouverait plusieurs lignes, bien que ces lignes ne contiennent que les chiffres. Est-il possible de sélectionner uniquement les lignes qui contiennent le nombre entier entre les virgules, par ex. "5282380" et pas seulement "52823" ou "2380"? –

Questions connexes