我有两个向量:
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"
如何创建我需要的向量?
您可以使用它,但可能有一个更简单的解决方案:
R> apply(expand.grid(vars, vis), 1, paste, collapse=".")
[1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3"
expand.grid
返回 a data.frame
which 当与 一起使用时apply
,apply
会将其转换为 a matrix
。这只是不必要的(在大数据上效率低下)。outer
给出一个matrix
并且也接受函数参数。它在处理大量数据时也会非常有效。
使用outer
:
as.vector(outer(vars, vis, paste, sep="."))
# [1] "SR.1" "PL.1" "SR.2" "PL.2" "SR.3" "PL.3"
另一种选择是使用 的each
参数rep
:
paste(rep(vars, each = length(vis)), vis, sep = ".")
我发现这比基于apply
or的解决方案更直接expand.grid
。
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
部分都由向量的元素替换。这个老问题已经有了一个公认的答案。但由于它被用作欺骗目标,我相信添加一个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.table
1.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 =".")]
分别
要保持问题中请求字符串的顺序,您可以使用这两种方法的以下两种修改:
改变向量的顺序并以相反的顺序组合
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"
其他一些选项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"
从该链接复制的 dplyr 选项
fruits <- tibble(
type = c("apple", "orange", "apple", "orange", "orange", "orange"),
year = c(2010, 2010, 2012, 2010, 2010, 2012),
size = factor(
c("XS", "S", "M", "S", "S", "M"),
levels = c("XS", "S", "M", "L")
),
weights = rnorm(6, as.numeric(size) + 2)
)
所有可能的组合,即所有组合都已定义,但不一定存在于数据中
fruits %>% expand(type)
#> # A tibble: 2 x 1
#> type
#> <chr>
#> 1 apple
#> 2 orange
fruits %>% expand(type, size)
#> # A tibble: 8 x 2
#> type size
#> <chr> <fct>
#> 1 apple XS
#> 2 apple S
#> 3 apple M
#> 4 apple L
#> 5 orange XS
#> 6 orange S
#> 7 orange M
#> 8 orange L
b<-fruits %>% expand(type, size, year)
#> # A tibble: 16 x 3
#> type size year
#> <chr> <fct> <dbl>
#> 1 apple XS 2010
#> 2 apple XS 2012
#> 3 apple S 2010
#> 4 apple S 2012
#> 5 apple M 2010
#> 6 apple M 2012
#> 7 apple L 2010
#> 8 apple L 2012
#> 9 orange XS 2010
#> 10 orange XS 2012
#> 11 orange S 2010
#> 12 orange S 2012
#> 13 orange M 2010
#> 14 orange M 2012
#> 15 orange L 2010
#> 16 orange L 2012
然后是简单的粘贴
b <- fruits %>% expand(type, size, year) %>%
mutate(., pasted=paste(type, size, year, sep="."))