【问题标题】:Correct way to concatenate lists of strings in R在R中连接字符串列表的正确方法
【发布时间】:2016-04-19 11:17:54
【问题描述】:

惯用在 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 的这种用法被认为比上面的列表推导式的等效用法更复杂(即,更少表达)。

【问题讨论】:

  • @brittenb 未按问题要求生成向量。
  • @zacdav 是的,我现在正在查看输出,我很困惑为什么它没有产生预期的输出。我会删除评论。
  • 有点直接翻译:mapply(function(x,y) sprintf("%s_%s", x, y), rep(titles, each=length(subtitles)), subtitles)跨度>
  • 在这个例子中,R 比 Python 更“多彩”...想知道每个人都能想到多少种不同的方式...

标签: r string


【解决方案1】:

有几种方法可以解决这个问题,或者使用“outer()”函数将函数定义为两个向量的矩阵乘积,如下所示:

outer(titles, sub.titles, paste, sep='_')

然后使用expand.grid()将其从矩阵转换为向量,或将输入转换为数据帧

do.call(paste, expand.grid(titles, sub.titles, sep='_', stringsAsFactors=FALSE))

【讨论】:

  • 你可以把它包装成c,就像c(outer(titles, sub.titles, paste, sep='_'))一样
  • 优雅。这几乎产生了正确的输出。不幸的是,生成的组件顺序错误。 (我已经更新了问题以澄清这一点。)转置解决了这个问题:c(t(outer(...)))
【解决方案2】:

do.callpasteexpand.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

【讨论】:

  • 确定它是基础 R ;) 但我经常使用 Curry。也在寻找一个优雅的使用tidyr 的衬里,但unite_(expand.grid(titles, sub.titles), everything()) 似乎不起作用
  • 既然您解决了我的问题,您可以将其发布为答案。
【解决方案3】:
apply(expand.grid(titles, sub.titles), 1, paste, collapse = "_")

expand.gridtitlessub.titles 之间创建一个组合矩阵。
apply 向下移动组合矩阵并将它们粘贴在一起。

【讨论】:

    【解决方案4】:

    试试这个代码:

    unlist(lapply(1:length(titles), function(x){paste(titles[x], sub.titles, sep="_")}))

    【讨论】:

      【解决方案5】:

      此代码也有效:as.vector(outer(titles, subtitles, FUN=paste, sep="_"))

      outer 本质上对每个向量中的每个元素执行一个函数元素。所以它会从titles 中获取每个元素,并对subtitles 中的每个元素执行一个函数。默认函数是乘法,但我们通过将新参数传递给FUN 参数来更改该默认值。在我们的新函数中使用的参数附加在逗号之后。所以我们告诉 R 从titles 中取出第一个元素并将其与subtitles 中的每个元素粘贴在一起,并用“_”分隔这两个元素。然后使用titles 中的第二个元素再次执行此操作。

      【讨论】:

        【解决方案6】:
        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"
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-03-25
          • 1970-01-01
          • 1970-01-01
          • 2014-08-26
          • 2017-11-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多