2017-08-05 3 views
3

J'essaie d'extraire des informations d'une table et j'essaie d'éviter pour boucles ou appliquer des fonctions de type.Utilisez ifelse pour extraire des informations d'une matrice

Supposons un vecteur m

m=c(1:20) 
m 
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 

et une matrice g

x1=c(0,1,0,1,2,0,1,2,3,0,1,2,3,4,0,1,2,3,4,5) 
x2=c(1,0,2,1,0,3,2,1,0,4,3,2,1,0,5,4,3,2,1,0) 
u=.4*x1^.5+.6*x2^.5 
g=cbind(x1,x2,u) 
g 
     x1 x2   u 
[1,] 0 1 0.6000000 
[2,] 1 0 0.4000000 
[3,] 0 2 0.8485281 
[4,] 1 1 1.0000000  
[5,] 2 0 0.5656854 
[6,] 0 3 1.0392305 
[7,] 1 2 1.2485281 
[8,] 2 1 1.1656854 
[9,] 3 0 0.6928203 
[10,] 0 4 1.2000000 
[11,] 1 3 1.4392305 
[12,] 2 2 1.4142136 
[13,] 3 1 1.2928203 
[14,] 4 0 0.8000000 
[15,] 0 5 1.3416408 
[16,] 1 4 1.6000000 
[17,] 2 3 1.6049159 
[18,] 3 2 1.5413485 
[19,] 4 1 1.4000000 
[20,] 5 0 0.8944272 

je veux pour chaque élément de m, pour vérifier si la somme g [1] + g [2] est égal à cet élément. Pour tous les cas où la condition est VRAIE, je veux que mon code retourne la position de celle qui a la plus grande valeur de g [, 3]. Par exemple, lorsque m = 5, la condition x [, 1] + x [, 2] == 5 est VRAIE à 15,16,17,18,19 et 20. Sur cet 6, l'entrée 17 a la valeur la plus élevée Donc, je veux que mon code retourne la valeur 17.

Donc à la fin, je m'attendrais à un vecteur de longueur = longueur (m), qui indiquera pour chaque élément de m, où est la valeur maximale de g [, 3] qui satisfait à la condition ci-dessus. Le vecteur doit être quelque chose comme ceci:

1,4,7,11,17,0,0,0,0,0,0...,0 

où lorsque m = 1, la ligne où g [1] + g [2] == 1 est une rangée lorsque m = 2, la ligne où g [, 1] + g [, 2] == 2 est la ligne 4 et ainsi de suite.

Actuellement j'utilise appliquer sur chaque ligne de g, mais ce processus est répété des milliers de fois, et mon code est très lent. Pour accélérer les choses, j'ai recouru à pour essayer de faire les choses de manière vectorisée.

Ce que je suis en train de faire est la suivante:

ifelse(m>0,which(g[,3]==max(g[which(g[,1]+g[,2]==m),3])),0) 

Quand je courais ce que je reçois

[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 

alors que si je remplace m avec 5, elle retourne un vecteur de 17s . Il semble qu'il n'utilise que le premier élément de m au lieu du vecteur entier. Toute suggestion sur la façon dont je peux faire ce travail, ou une alternative qui pourrait faire le même travail est plus que bienvenue.

+0

peut u montrer la sortie attendue? Essayez 'which (externe (m, g [, 1] + g [, 2], '=='), arr.ind = TRUE)' ou peut être 'g [, 3] [max.col (externe (m , g [, 1] + g [, 2], '=='))] ' – akrun

+0

Merci. J'ai édité la question pour inclure la sortie attendue. – KGeor

Répondre

2

Nous pourrions utiliser outer avec max.col

m1 <- t(outer(g[,1] + g[,2], m, `==`)* g[,3]) 
max.col(m1) * (rowSums(m1!= 0) !=0) 
#[1] 1 4 7 11 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
+1

Cela a fait le travail! Merci beaucoup! – KGeor