如何在不重复短向量元素的情况下,对不同长度的向量进行cbind或rbind ?

时间:2021-07-06 20:24:52
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  

I want an output like below

我希望输出如下所示

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

3 个解决方案

#1


50  

The trick is to make all your inputs the same length.

关键是要让所有的输入都保持相同的长度。

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

If you want you output to be an array, then cbind works, but you get additional NA values to pad out the rectangle.

如果您希望输出是一个数组,那么cbind就可以工作,但是您将获得额外的NA值来填充矩形。

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

To get rid of the NAs, the output must be a list.

为了去掉NAs,输出必须是一个列表。

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: I swapped mapply(..., SIMPLIFY = FALSE) for Map.

编辑:我交换mapp(…,对Map来说,简单化= FALSE。

#2


7  

I came across similar problem and I would like to suggest that additional solution that some, I hope, may find useful. The solution is fairly straightforward and makes use of the qpcR package and the provided cbind.na function.

我遇到了类似的问题,我想提出另一个解决方案,我希望有些人能找到有用的。该解决方案相当简单,并使用qpcR包和提供的cbind。na的功能。

Example

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

Results

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

Side comments

Following the OP's original example, column names can be easily removed:

按照OP的原始示例,可以轻松删除列名:

colnames(dta) <- NULL

the operation would produce the desired output in full:

该操作将产生所需的全部输出:

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

#3


1  

Helper function...

Helper函数…

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
}

Examples:

例子:

> 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


50  

The trick is to make all your inputs the same length.

关键是要让所有的输入都保持相同的长度。

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

If you want you output to be an array, then cbind works, but you get additional NA values to pad out the rectangle.

如果您希望输出是一个数组,那么cbind就可以工作,但是您将获得额外的NA值来填充矩形。

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

To get rid of the NAs, the output must be a list.

为了去掉NAs,输出必须是一个列表。

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: I swapped mapply(..., SIMPLIFY = FALSE) for Map.

编辑:我交换mapp(…,对Map来说,简单化= FALSE。

#2


7  

I came across similar problem and I would like to suggest that additional solution that some, I hope, may find useful. The solution is fairly straightforward and makes use of the qpcR package and the provided cbind.na function.

我遇到了类似的问题,我想提出另一个解决方案,我希望有些人能找到有用的。该解决方案相当简单,并使用qpcR包和提供的cbind。na的功能。

Example

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

Results

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

Side comments

Following the OP's original example, column names can be easily removed:

按照OP的原始示例,可以轻松删除列名:

colnames(dta) <- NULL

the operation would produce the desired output in full:

该操作将产生所需的全部输出:

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

#3


1  

Helper function...

Helper函数…

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
}

Examples:

例子:

> 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