web-dev-qa-db-fra.com

Comment lier ou lier des vecteurs de longueurs différentes sans répéter les éléments des vecteurs plus courts?

cbind(1:2, 1:10)  
     [,1] [,2]  
  [1,]    1    1  
  [2,]    2    2  
  [3,]    1    3  
  [4,]    2    4  
  [5,]    1    5  
  [6,]    2    6  
  [7,]    1    7  
  [8,]    2    8  
  [9,]    1    9  
 [10,]    2   10  

Je veux une sortie comme ci-dessous

[,1] [,2]  
[1,] 1 1  
[2,] 2 2  
[3,]   3  
[4,]   4  
[5,]   5  
[6,]   6  
[7,]   7  
[8,]   8  
[9,]   9  
[10,]  10  
45
Chares

L'astuce consiste à faire toutes vos entrées de la même longueur.

x <- 1:2
y <- 1:10
n <- max(length(x), length(y))
length(x) <- n                      
length(y) <- n

Si vous voulez que votre sortie soit un tableau, alors cbind fonctionne, mais vous obtenez des valeurs supplémentaires de NA pour remplir le rectangle.

cbind(x, y)
       x  y
 [1,]  1  1
 [2,]  2  2
 [3,] NA  3
 [4,] NA  4
 [5,] NA  5
 [6,] NA  6
 [7,] NA  7
 [8,] NA  8
 [9,] NA  9
[10,] NA 10

Pour se débarrasser des NAs, la sortie doit être une liste.

Map(function(...) 
   {
      ans <- c(...)
      ans[!is.na(ans)]
   }, as.list(x), as.list(y)
)
[[1]]
[1] 1 1

[[2]]
[1] 2 2

[[3]]
[1] 3

[[4]]
[1] 4

[[5]]
[1] 5

[[6]]
[1] 6

[[7]]
[1] 7

[[8]]
[1] 8

[[9]]
[1] 9

[[10]]
[1] 10

EDIT: J'ai échangé mapply(..., SIMPLIFY = FALSE) contre Map.

63
Richie Cotton

J'ai rencontré un problème similaire et je voudrais suggérer une solution supplémentaire que certains, je l'espère, pourraient trouver utile. La solution est assez simple et utilise le paquet qpcR et le --- = cbind.na fonction.

Exemple

x <- 1:2
y <- 1:10
dta <- qpcR:::cbind.na(x, y)

Résultats

> head(dta)
      x y
[1,]  1 1
[2,]  2 2
[3,] NA 3
[4,] NA 4
[5,] NA 5
[6,] NA 6

Commentaires annexes

En suivant l'exemple original de l'OP , les noms de colonne peuvent être facilement supprimés:

colnames(dta) <- NULL

l'opération produirait la sortie souhaitée dans son intégralité:

> head(dta)
     [,1] [,2]
[1,]    1    1
[2,]    2    2
[3,]   NA    3
[4,]   NA    4
[5,]   NA    5
[6,]   NA    6
14
Konrad

Fonction d'assistance ...

bind.pad <- function(l, side="r", len=max(sapply(l,length)))
{
  if (side %in% c("b", "r")) {
    out <- sapply(l, 'length<-', value=len)
  } else {
    out <- sapply(sapply(sapply(l, rev), 'length<-', value=len, simplify=F), rev)}
  if (side %in% c("r", "l")) out <- t(out)
  out
}

Exemples:

> l <- lapply(c(3,2,1,2,3),seq)
> lapply(c("t","l","b","r"), bind.pad, l=l, len=4)
[[1]]
     [,1] [,2] [,3] [,4] [,5]
[1,]   NA   NA   NA   NA   NA
[2,]    1   NA   NA   NA    1
[3,]    2    1   NA    1    2
[4,]    3    2    1    2    3

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

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

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