2017-06-15 3 views
2

Je veux sous-ensemble mon dataframe sous la condition que le nombre de variables correspondant est égal à un nombre, par exempleSubset un dataframe où nombre de variables correspondant est k

example <- rbind(sample(letters[1:5]), 
      sample(letters[1:5]), 
      sample(letters[1:5]), 
      sample(letters[1:5]), 
      sample(letters[1:5])) 


example 

    [,1] [,2] [,3] [,4] [,5] 
[1,] "b" "a" "d" "e" "c" 
[2,] "e" "c" "a" "d" "b" 
[3,] "c" "a" "d" "b" "e" 
[4,] "b" "d" "e" "c" "a" 
[5,] "b" "c" "e" "d" "a" 

si je voulais mon numéro de les variables correspondantes étaient 3, les deux dernières lignes seraient sélectionnées, puisqu'elles ont 3 lettres en commun (même endroit et même lettre).

+0

Chaque ligne de la matrice doit être comparée à toutes les autres lignes dans la matrice et si elle correspond au seuil (ici 3) pour une ligne alors à la fois les lignes seraient être sélectionné? –

+0

Exactement, les lignes qui ont 3 éléments en commun doivent être sélectionnées. –

Répondre

2

Création des données reproductibles

set.seed(47) 
example <- rbind(sample(letters[1:5]), 
       sample(letters[1:5]), 
       sample(letters[1:5]), 
       sample(letters[1:5]), 
       sample(letters[1:5])) 

example 
# [,1] [,2] [,3] [,4] [,5] 
#[1,] "e" "b" "c" "d" "a" 
#[2,] "d" "b" "e" "c" "a" 
#[3,] "a" "c" "e" "b" "d" 
#[4,] "e" "b" "a" "c" "d" 
#[5,] "a" "c" "b" "e" "d" 

Une approche que je pouvais penser est en utilisant double boucle

n <- 3 
example[sapply(apply(example, 1, function(x) 
        which(colSums(x == t(example)) >= n)), length) > 1, ] 


# [,1] [,2] [,3] [,4] [,5] 
#[1,] "a" "c" "e" "b" "d" 
#[2,] "a" "c" "b" "e" "d" 

Ici, nous comparons chaque ligne avec toutes les autres lignes, élément sage et de compter le nombre de comparaisons égales s'il est égal ou supérieur au seuil (n). L'autre boucle consiste à filtrer les lignes qui lui sont égales.

0

Une alternative consiste à utiliser deux fois combn, d'abord pour énumérer les paires et ensuite pour effectuer les comparaisons par paire.

En utilisant l'exemple de Ronak-shah,

combn(seq_len(nrow(example)), 2)[, combn(seq_len(nrow(example)), 2, 
           FUN=function(x) sum(example[x[1],] == example[x[2],]) >= 3)] 
[1] 3 5 

qui indique les lignes à garder.

Cela retournera souvent une matrice et l'ensemble des lignes peut être répété. Par exemple, la fixation du seuil à 2, nous obtenons

 [,1] [,2] [,3] [,4] 
[1,] 1 1 2 3 
[2,] 2 4 4 5 

pour obtenir cela en quelque chose d'utile, utilisez c pour transformer le résultat dans un vecteur, puis unique laisser tomber les lignes répétées. Pendant que nous y sommes, nous pouvons tout aussi bien intégrer le tout dans une fonction qui permettra la sélection du seuil.

rowKeeper <- function(myMat, thresh) { 
    myMat[unique(c(combn(seq_len(nrow(myMat)), 2)[, 
     combn(seq_len(nrow(example)), 2, 
       FUN=function(x) sum(myMat[x[1],] == myMat[x[2],]) >= thresh)])),] 
} 

Ensuite, essayez-le

rowKeeper(example, 3) 
    [,1] [,2] [,3] [,4] [,5] 
[1,] "a" "c" "e" "b" "d" 
[2,] "a" "c" "b" "e" "d"