【问题标题】:Concatenating R strings with a separator - except the first time用分隔符连接 R 字符串 - 第一次除外
【发布时间】:2021-09-05 06:21:27
【问题描述】:

我有一个对数据框进行一些检查的过程,每次检查检查是否通过时,我都想将文本添加到带有分隔符的列中。所以假设在第 2 行和第 3 行测试通过后,msg 列中包含“first”。然后第二个测试更新了ok 列,并且对于第 1 行和第 2 行是正确的,给出以下内容:

> d = data.frame(ok=c(TRUE,TRUE,FALSE,FALSE), msg=c("", "first","first",""))
> d
     ok   msg
1  TRUE      
2  TRUE first
3 FALSE first
4 FALSE  

因此,下一步将仅在第 1 行和第 2 行的 msg 列中添加“第二个”,结果是:

     ok          msg
1  TRUE       second
2  TRUE first;second
3 FALSE        first
4 FALSE            

我不知道该怎么做。第一次尝试在初始情况下留下了一个领先的分隔符:

> paste(d$msg[d$ok],"second", sep=";")
[1] ";second"      "first;second"

这会返回一个长度为 3 的向量,这显然是错误的:

> paste(c(d$msg[d$ok],"second"), sep=";")
[1] ""       "first"  "second"

任何带有collapse 的东西都会返回一个长度为1 的向量,这也是错误的。

大锤解决方案是使用上面的第一个努力,然后在最后去除任何前导分隔符,但这很难看。我希望有更整洁的东西。

解决方案应该只使用 base R 函数,并且最初的“空字符串”不一定是 "" - 但我玩过 NA 却一无所获。比我的大锤更简洁的解决方案(在我看来)会被接受。

【问题讨论】:

  • 也许为每个测试添加新列,然后 apply(df[flag_cols], 1, function(x) paste(x[nzchar(x)], collapse=';'))?跨度>
  • 也许正则表达式可以像out <- paste(d$msg[d$ok],"second", sep=";")gsub('^\\;|\\.$', '', out) 一样有用。或组合版本gsub('^\\;|\\.$', '', paste(d$msg[d$ok],"second",sep=";"))
  • @maydin 那是我的大锤,除了我使用sub 而不是gsub 它会剥离第一个分隔符实例,我可以确保始终有第一个分隔符实例。
  • Ops.. 我没有阅读全文。对不起。
  • 可能是sapply(d$msg[d$ok], function(x) (paste(c(x[nchar(x)>0], "second"), collapse=";"))) ?

标签: r string


【解决方案1】:

使用您的数据框 d,我们可以使用基本的 ifelse 函数来解决您的分隔符问题:

d$msg <- as.character(d$msg)

d$msg[d$ok] <- ifelse(d$msg[d$ok] == "", "second", paste(d$msg[d$ok], "second", sep=";"))

输出:

     ok          msg
1  TRUE       second
2  TRUE first;second
3 FALSE        first
4 FALSE             

【讨论】:

    【解决方案2】:

    你可以编写一个函数来测试空字符串的情况:

    strAppend <- function(a, b, sep=";") {
      paste0(a, c("", sep)[1+nchar(a)>0], b)
    #  paste0(a, c(sep,"")[1+(a=="")], b)    #Alternative
    }
    
    strAppend(d$msg[d$ok], "second")
    #[1] "second"       "first;second"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      • 2016-09-15
      • 1970-01-01
      • 2015-09-26
      • 2019-01-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多