在R中将字符向量中的行合并

3

我有一个字符向量(content),在R语言中大约有50000行。然而,当从文本文件读取时,其中一些行是分开的,实际上它们不应该分开。具体来说,这些行看起来像这样:

[1] hello,
[2] world
[3] ""
[4] how
[5] are 
[6] you
[7] ""

我希望将这些行合并,使其看起来像这样:
[1] hello, world
[2] how are you

我已尝试编写一个 for 循环:

for(i in 1:length(content)){
    if(content[i+1] != ""){
        content[i+1] <- c(content[i], content[i+1])
    }
}  

但是当我运行循环时,出现了错误:需要TRUE / FALSE的地方缺少值。

有人能建议一种更好的方法来做这件事吗,也许甚至不使用循环?

谢谢!

编辑: 实际上,我正在尝试将其应用于一个包含成千上万行的文档语料库。有什么想法可以将这些解决方案转化为可应用于每个文档内容的函数吗?


你会收到错误提示,因为缺少 content[i+1] - Heroka
@Heroka,你能再解释一下吗? - dc3
2
你正在遍历内容的长度,然后访问长度为内容长度+1的内容。这会产生一个缺失值。但是这种方法不会轻松地得到你想要的输出,我正在为你寻找答案。 - Heroka
5个回答

4

你不需要使用循环来实现这个。

x <- c("hello,", "world", "", "how", "\nare", "you", "")

dummy <- paste(
  c("\n", sample(letters, 20, replace = TRUE), "\n"), 
  collapse = ""
) # complex random string as a split marker
x[x == ""] <- dummy #replace empty string by split marker
y <- paste(x, collapse = " ") #make one long string
z <- unlist(strsplit(y, dummy)) #cut the string at the split marker
gsub(" $", "", gsub("^ ", "", z)) # remove space at start and end

不错。小问题:你的解决方案生成带有空格开头的句子。这个方案可扩展到50000行吗? - Heroka
3
我们能确定没有任何字符串包含 \n 吗? - Roland

2
我认为还有更优雅的解决方案,但这可能对您有用:
chars <- c("hello,","world","","how","are","you","")
###identify groups that belong together (id increases each time a "" is found)
ids <- cumsum(chars=="")

#split vector (an filter out "" by using the select vector)
select <- chars!=""
splitted <- split(chars[select], ids[select])

#paste the groups together
res <- sapply(splitted,paste, collapse=" ")

#remove names(if necessary, probably not)
res <- unname(res) #thanks @Roland

> res
[1] "hello, world" "how are you"

我也打算提出这个建议。你还可以在最后一步使用 unname - Roland
@Roland 不知道那个,谢谢。已编辑答案。 - Heroka
内部实际上做的就是你正在做的事情。只不过更方便和易读一些。 - Roland
@Heroka - 我已经编辑了上面的问题,但是你有没有想过如何将其应用到文本文件语料库中? - dc3
@Heroka 在我稍微操作过的语料库上使用了lapply。谢谢! - dc3

1

这里提供了一种不同的方法,使用 data.table 可能比使用 for 或者 *apply 循环更快:

library(data.table)
dt <- data.table(x)
dt[, .(paste(x, collapse = " ")), rleid(x == "")][V1 != ""]$V1
#[1] "hello, world" "how are you" 

样本数据:

x <- c("hello,", "world", "", "how", "are", "you", "")

0

""替换为您稍后可以拆分的内容,然后将字符合并在一起,最后使用strsplit()。在这里,我使用了换行符,因为如果您只是粘贴它,您可以获得不同行的输出,例如cat(txt3)将在单独的行上输出每个短语。

txt <-  c("hello", "world", "", "how", "are", "you", "", "more", "text", "")
txt2 <- gsub("^$", "\n", txt)
txt3 <- paste(txt2, collapse = " ")
unlist(strsplit(txt3, "\\s\n\\s*"))
## [1] "hello world" "how are you" "more text"

0

另一种添加方法:

tapply(x[x != ''], cumsum(x == '')[x != '']+1, paste, collapse=' ')
#             1              2              3 
#"hello, world"  "how are you"    "more text" 

按非空字符串分组。并将元素按组粘合在一起。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接