2011-04-03 3 views
21

J'ai plusieurs vecteurs de longueur inégale et je voudrais les cbind eux. J'ai mis les vecteurs dans une liste et j'ai essayé de combiner l'utilise do.call(cbind, ...):Combinaison de vecteurs (cbind) de longueur différente

nm <- list(1:8, 3:8, 1:5) 
do.call(cbind, nm) 

#  [,1] [,2] [,3] 
# [1,] 1 3 1 
# [2,] 2 4 2 
# [3,] 3 5 3 
# [4,] 4 6 4 
# [5,] 5 7 5 
# [6,] 6 8 1 
# [7,] 7 3 2 
# [8,] 8 4 3 
# Warning message: 
# In (function (..., deparse.level = 1) : 
#   number of rows of result is not a multiple of vector length (arg 2) 

Comme prévu, le nombre de lignes dans la matrice résultante est la longueur du vecteur le plus long, et les valeurs de la les vecteurs plus courts sont recyclés pour compenser la longueur. Au lieu de cela, je voudrais remplir les vecteurs plus courts avec NA valeurs pour obtenir la même longueur que le plus long vecteur. Je voudrais que la matrice ressemble à ceci:

#  [,1] [,2] [,3] 
# [1,] 1 3 1 
# [2,] 2 4 2 
# [3,] 3 5 3 
# [4,] 4 6 4 
# [5,] 5 7 5 
# [6,] 6 8 NA 
# [7,] 7 NA NA 
# [8,] 8 NA NA 

Comment puis-je faire cela?

+1

flash de brillance: nm <- cbind (z1, c (z2, rep (NA, longueur (z1) -longueur (z2)))) – Nick

Répondre

5

Vous devez remplir les vecteurs avec NA avant d'appeler do.call.

nm <- list(1:8,3:8,1:5) 

max_length <- max(unlist(lapply(nm,length))) 
nm_filled <- lapply(nm,function(x) {ans <- rep(NA,length=max_length); 
            ans[1:length(x)]<- x; 
            return(ans)}) 
do.call(cbind,nm_filled) 
3

Ceci est une version plus courte de la solution de Wojciech.

nm <- list(1:8,3:8,1:5) 
max_length <- max(sapply(nm,length)) 
sapply(nm, function(x){ 
    c(x, rep(NA, max_length - length(x))) 
}) 
+2

Il est toujours préférable d'utiliser 'vapply' plutôt que' sapply' car cela vous garantira le type de sortie que vous attendez. – hadley

+0

@hadley Pourriez-vous élaborer sur votre commentaire? Je ne comprends pas la différence entre Vapply et Sapply transféré à ce problème. – guerda

+1

spply est dangereux à programmer avec car il n'est pas de type stable - en fonction de la longueur de 'nm' vous obtiendrez différents types – hadley

21

Vous pouvez utiliser l'indexation, si vous indexez un nombre au-delà de la taille de l'objet retourne NA. Cela fonctionne pour un nombre arbitraire de lignes définies avec foo:

nm <- list(1:8,3:8,1:5) 

foo <- 8 

sapply(nm, '[', 1:foo) 

EDIT:

Ou dans une ligne en utilisant le plus grand vecteur nombre de lignes:

sapply(nm, '[', seq(max(sapply(nm,length)))) 

De R 3.2.0 vous pouvez utiliser lengths ("obtenir la longueur de chaque élément d'une liste") au lieu de sapply(nm, length):

sapply(nm, '[', seq(max(lengths(nm)))) 
+2

qu'est-ce que '[' signifie!? – user702846

+0

''['' est le nom de l'opérateur '[' que vous utilisez dans l'indexation ('foo [1:10]'). Voir aussi '? '['' –

+0

La solution d'une ligne échoue si la première colonne est plus courte que les deux autres. – bshor

Questions connexes