使用所有向量元素的组合粘贴两个向量


76

我有两个向量:

vars <- c("SR", "PL")
vis <- c(1,2,3)

基于这些向量,我想创建以下向量:

"SR.1"  "SR.2"  "SR.3"  "PL.1"  "PL.2"  "PL.3"

paste我有以下结果:

paste(vars, vis, sep=".")
 [1] "SR.1" "PL.2" "SR.3"

如何创建所需的向量?

Answers:


88

您可以使用此方法,但可能有一个更简单的解决方案:

R> apply(expand.grid(vars, vis), 1, paste, collapse=".")
[1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3"

expand.grid还给一个data.frame与使用时applyapply将其转换为matrix。这只是不必要的(并且在大数据上效率低下)。outer给出一个matrix并且也接受函数参数。在海量数据上也将非常有效。

使用outer

as.vector(outer(vars, vis, paste, sep="."))
# [1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3"

2
expand.grid返回可如果你想为了进行排序表SR,SR,PL,PL...,而不是SR,PL,SR,PL
rmf

26

另一种选择是使用以下each参数rep

paste(rep(vars, each = length(vis)), vis, sep = ".")

我发现这比基于apply或的解决方案更直接expand.grid


14

sprintf结合使用的另一种选择expand.grid

eg <- expand.grid(vis, vars)
sprintf('%s.%s', eg[,2], eg[,1])

这使:

[1] "SR.1" "SR.2" "SR.3" "PL.1" "PL.2" "PL.3"

说明:

  • 随着expand.grid创建两个向量的所有组合。
  • sprintf根据指定的格式('%s.%s')将两个向量粘贴在一起。%s格式的每个部分均由向量的元素替换。

1
我认为这是所有建议中最优雅的解决方案!
JelenaČuklina

9

要保持问题中请求的字符串的顺序,可以对这两种方法使用以下两种修改:

更改向量的顺序并以相反的顺序合并

apply(expand.grid(vis, vars), 1, function(x) paste(x[2], x[1], sep=".")) 
[1] "SR.1" "SR.2" "SR.3" "PL.1" "PL.2" "PL.3"

或在转换为向量之前转置矩阵:

as.vector(t(outer(vars, vis, paste, sep="."))) 
[1] "SR.1" "SR.2" "SR.3" "PL.1" "PL.2" "PL.3"

8

这个老问题已经有了一个可以接受的答案。但是由于它被用作重复目标,因此我相信添加一个data.table使用交叉连接功能的解决方案是值得的CJ()

library(data.table) 
options(datatable.CJ.names=FALSE) # required with version version 1.12.0+
CJ(vars, vis)[, paste(V1, V2, sep =".")]
#[1] "PL.1" "PL.2" "PL.3" "SR.1" "SR.2" "SR.3"

如果原始订单很重要:

CJ(vars, vis, sorted = FALSE)[, paste(V1, V2, sep =".")]
#[1] "SR.1" "SR.2" "SR.3" "PL.1" "PL.2" "PL.3"

编辑:CJ()更改了默认行为与版本1.12.0

版本1.12.0(第3点)的发行说明中所述,默认选项options(datatable.CJ.names=TRUE)已更改。CJ()现在会自动将其输入自动命名as data.table()

因此,以上代码必须针对data.table1.12.0及更高版本进行修改:

library(data.table)   ### version 1.12.0+
CJ(vars, vis)[, paste(vars, vis, sep =".")]

CJ(vars, vis, sorted = FALSE)[, paste(vars, vis, sep =".")]

分别


2

其他一些选项purrr

library(purrr)
cross(list(vars, vis)) %>% map_chr(paste, sep = ".", collapse = ".")
#[1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3"

我们也可以使用 cross2

cross2(vars, vis) %>%  map_chr(paste, sep = ".", collapse = ".")
#[1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.