【发布时间】: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=";")))?