【问题标题】:Equivalent to cumsum for string in R [duplicate]相当于R中字符串的cumsum [重复]
【发布时间】:2016-02-12 20:46:02
【问题描述】:

我正在寻找一种方法来做相当于 R 中字符串/字符格式文本而不是数字的累积总和的方法。应该连接不同的文本字段。

例如在数据框“df”中:

A 列包含输入,B 列包含所需结果。

  A        B
1 banana   banana 
2 boats    banana boats
3 are      banana boats are
4 awesome  banana boats are awesome

目前我正在通过以下循环解决这个问题

df$B <- ""

for(i in 1:nrow(df)) {
    if (length(df[i-1,"A"]) > 0) {
        df$B[i] <- paste(df$B[i-1],df$A[i])
    } else {
        df$B[i] <- df$A[i]
    }
}

我想知道是否存在更优雅/更快的解决方案。

【问题讨论】:

  • 根本不是“cumsum”!
  • 性能有问题吗?
  • 认为经典的cumpaste首先出现在here(可能重复)。感谢@alexis_laz。
  • Another similar Q&A,尽管也像上面的答案一样“按组”。但“按组”很少是棘手的部分......
  • 感谢您的所有回答!发现 Reduce 是最快的,因此标记为最佳答案。抱歉,如果这是重复的!我似乎搜索了错误的字词。

标签: r


【解决方案1】:
(df$B <- Reduce(paste, as.character(df$A), accumulate = TRUE))
# [1] "banana"     "banana boats"      "banana boats are"    "banana boats are awesome"

【讨论】:

  • 令人印象深刻,而且速度极快。 (在 1000 个字符串的输入向量上,比我的解决方案快 20 倍)
  • @Heroka Reduce 只是一个 for 循环。
  • @Roland 等很聪明,但在我的机器上 Reduce 把其他答案吹出了公园。我认为是accumulate = TRUE
  • @Heroka 嗯,是的。显然,它比您的方法更好地处理累积,但它只是很好的语法糖。如果您查看内部代码,您会看到一个标准的for 循环。
  • @Roland 这不是“只是”一个 for 循环。还有很多事情可以解释速度的提高。首先,您已经强制调用(请参阅?forceAndCall。更重要的是,函数Reduce 已经编译为字节码。任何编译后的代码都将优于“手工制作”的 for 循环。所以称它为语法糖正在做对功能的不公正。
【解决方案2】:

我们可以试试

 i1 <- sequence(seq_len(nrow(df1)))
 tapply(df1$A[i1], cumsum(c(TRUE,diff(i1) <=0)),
                     FUN= paste, collapse=' ')

或者

 i1 <- rep(seq(nrow(df1)), seq(nrow(df1)))
 tapply(i1, i1, FUN= function(x) 
          paste(df1$A[seq_along(x)], collapse=' ') )

【讨论】:

    【解决方案3】:

    不知道是不是更快,但至少代码更短:

    sapply(seq_along(df$A),function(x){paste(A[1:x], collapse=" ")})
    

    感谢 Rolands 的评论,我意识到这是 for 循环可能有用的罕见情况之一,因为它为我们节省了重复索引。它与 OP 不同,因为它从 2 开始,省去了 forloop 中的 if 语句。

    res <- c(NA, length(df1$A))
    res[1] <- as.character(df1$A[1])
    for(i in 2:length(df1$A)){
       res[i] <- paste(res[i-1],df1$A[i])
     }
    res
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-09
      • 1970-01-01
      相关资源
      最近更新 更多