在R中执行以下字符串连接的惯用方法是什么?
给出两个字符串向量,如下所示,
titles <- c("A", "B")
sub.titles <- c("x", "y", "z")
我想制作矢量
full.titles <- c("A_x", "A_y", "A_z", "B_x", "B_y", "B_z")
显然,这可以通过两个for循环来完成。但是,我想知道R中的“惯用”(即优雅和自然)解决方案是什么。
在Python中,惯用解决方案可能如下所示:
titles = ['A', 'B']
subtitles = ['x', 'y', 'z']
full_titles = ['_'.join([title, subtitle])
for title in titles for subtitle in subtitles]
R是否允许相似程度的表达?
备注
迄今为止提出的解决方案之间的共识是,在R中执行此操作的惯用方法基本上是
full.titles <- c(t(outer(titles, sub.titles, paste, sep = "_")))
有趣的是,这在Python中有一个(几乎)字面翻译:
full_titles = map('_'.join, product(titles, subtitles))
其中product
是itertools模块中的笛卡尔积函数。但是,在Python中,map
的这种使用被认为比上面的列表理解的等效使用更复杂 - 即 less 表达 -
答案 0 :(得分:5)
有两种方法可以解决这个问题,或者使用'outer()'函数将函数定义为两个向量的矩阵乘积,如下所示:
outer(titles, sub.titles, paste, sep='_')
然后使用expand.grid()
do.call(paste, expand.grid(titles, sub.titles, sep='_', stringsAsFactors=FALSE))
答案 1 :(得分:3)
将do.call
与paste
和expand.grid
sort(do.call(paste, c(sep='_', expand.grid(titles, sub.titles))))
#[1] "A_x" "A_y" "A_z" "B_x" "B_y" "B_z"
或使用tidyr::unite
结合expand.grid
unite(expand.grid(titles, sub.titles), Res, everything()) %>% .$Res
答案 2 :(得分:2)
apply(expand.grid(titles, sub.titles), 1, paste, collapse = "_")
expand.grid
创建titles
和sub.titles
之间的组合矩阵
apply
沿着组合矩阵向下并将它们粘贴在一起。
答案 3 :(得分:1)
试试这段代码:
unlist(lapply(1:length(titles), function(x){paste(titles[x], sub.titles, sep="_")}))
答案 4 :(得分:1)
此代码也有效:as.vector(outer(titles, subtitles, FUN=paste, sep="_"))
outer
基本上对每个向量的每个元素执行元素功能。因此,它将从titles
中获取每个元素,并使用subtitles
中的每个元素执行一个函数。默认函数是乘法,但我们通过将新参数传递给FUN
参数来更改该默认值。我们的新函数中使用的参数将附加在逗号后面。所以我们告诉R从titles
获取第一个元素并将其与subtitles
中的每个元素粘贴在一起,并用“_”分隔这两个元素。然后使用titles
中的第二个元素再次执行此操作。
答案 5 :(得分:1)
full.titles <- paste0(expand.grid(titles,sub.titles)$Var1,'_',
expand.grid(titles,sub.titles)$Var2)
>full.titles
[1] "A_x" "B_x" "A_y" "B_y" "A_z" "B_z"