2017-01-21 1 views
0

J'ai une question sur les valeurs d'appariement entre deux vecteurs. Disons que j'ai un cadre de données vectorielles et:intersection avec la tolérance des vecteurs non égaux et ID

data.frame 
    value name      vector 2 
154.0031 A       154.0084 
154.0768 B       159.0344 
154.2145 C       154.0755 
154.4954 D       156.7758 
156.7731 E 
156.8399 F 
159.0299 G 
159.6555 H 
159.9384 I 

Maintenant, je veux comparer vecteur 2 avec des valeurs dans la trame de données avec une tolérance globale définie (par exemple + -0,005) qui est réglable et ajouter les noms correspondants au vecteur 2, donc j'obtenir un résultat comme celui-ci:

data.frame 
    value name      vector 2 name 
154.0031 A       154.0074 A 
154.0768 B       159.0334 G 
154.2145 C       154.0755 B 
154.4954 D       156.7758 E 
156.7731 E 
156.8399 F 
159.0299 G 
159.6555 H 
159.9384 I 

J'ai essayé d'utiliser intersect() mais il n'y a pas d'option pour la tolérance en elle?

Merci beaucoup!

Répondre

1

Ce résultat peut être obtenu grâce à outer, which et à la sous-sélection.

# calculate distances between elements of each object 
# rows are df and columns are vec 2 
myDists <- outer(df$value, vec2, FUN=function(x, y) abs(x - y)) 


# get the values that have less than some given value 
# using arr.ind =TRUE returns a matrix with the row and column positions 
matches <- which(myDists < 0.05, arr.ind=TRUE) 

data.frame(name = df$name[matches[, 1]], value=vec2[matches[, 2]]) 
name value 
1 A 154.0084 
2 G 159.0344 
3 B 154.0755 
4 E 156.7758 

Notez que cela ne renverra les éléments de vec2 avec des allumettes et retournera tous les éléments de df qui satisfont le seuil.

pour rendre les résultats robustes pour cela, utilisez

# get closest matches for each element of vec2 
closest <- tapply(matches[,1], list(matches[,2]), min) 

# fill in the names. 
# NA will appear where there are no obs that meet the threshold. 
data.frame(name = df$name[closest][match(as.integer(names(closest)), 
             seq_along(vec2))], value=vec2) 

Actuellement, cela renvoie le même résultat que ci-dessus, mais revenir NAs où il n'y a pas d'observation adéquate df.

données

S'il vous plaît fournir des données reproductibles si vous posez une question à l'avenir. Voir ci-dessous.

df <- read.table(header=TRUE, text="value name 
154.0031 A 
154.0768 B 
154.2145 C 
154.4954 D 
156.7731 E 
156.8399 F 
159.0299 G 
159.6555 H 
159.9384 I") 

vec2 <- c(154.0084, 159.0344, 154.0755, 156.7758) 
+0

Merci, ça aide beaucoup! Sry pour la chose de données, je fournirai un ensemble de données approprié pour de futures questions. – JmO