2016-03-16 3 views
0

Предположим, у меня есть вектор строк (строк), который я очистил с веб-страницы .txt, используя readLines. Некоторые строки начинаются с «<», что обычно указывает на начало нового абзаца. Некоторые строки начинаются с буквы, что обычно указывает на то, что она подключена к линии перед ней. Я хочу уметь конкатенировать строки, относящиеся к одному и тому же абзацу.Как векторизовать функцию `paste` в R?

Мой план состоит в том, чтобы найти линии, начинающиеся с «<», и объединить все линии между двумя строками, начинающимися с «<». По сути, у меня есть список индексов. Например, я могу конкатенировать lines[1:3], lines[4:4], lines[5:9] и так далее. Есть ли способ векторизовать это? Я не могу просто сделать paste(lines[begin.index : end.index]), но это может дать вам представление о том, чего я надеюсь достичь.

Вот некоторые фиктивные данные, в качестве примера, так как мой фактические данные слишком долго:

[1] "<P> sampletextsampletext" 
[2] "sampletextsampletext</P>" 
[3] "<P> sampletext" 
[4] "sampletext" 
[5] "sampletext</P>" 
[6] "<P> sampletext </P>" 

Я хотел бы объединить линии 1 и 2 вместе, и любит 3, 4 и 5 вместе, и линия 6 останется прежним.

+4

Пожалуйста, включите образец данных. Ваша проблема не совсем понятна из описания. – nrussell

+7

Вы должны понимать, что запрос «как vectorize paste()» звучит очень странно для людей R, потому что paste() _is_ vectorized. Может быть, вы просто ищете аргумент 'collapse'? – joran

+1

Звучит так, как будто у вас есть группы линий (1: 3, 4: 4, 5: 9), и вам нужно знать, как применять 'paste' с аргументом' collapse' для каждой группы. 'dplyr' или' data.table' являются вашими друзьями здесь, хотя 'aggregate', вероятно, будет работать нормально. – Gregor

ответ

3

Если вы пытаетесь отделить узлы HTML, лучше использовать функции, которые понимают HTML. Это имеет то преимущество, что вам не нужно вручную находить стартовые и конечные теги.

# read in data 
lines <- c("<P> sampletextsampletext", 
      "sampletextsampletext</P>" , 
      "<P> sampletext", 
      "sampletext", 
      "sampletext</P>", 
      "<P> sampletext </P>") 

# load a simple HTML scraping/parsing package 
library(rvest) 

# find all `<p>` tags and their contents 
lines %>% paste(collapse = '') %>% read_html() %>% html_nodes('p') 
# {xml_nodeset (3)} 
# [1] <p> sampletextsampletextsampletextsampletext</p> 
# [2] <p> sampletextsampletextsampletext</p> 
# [3] <p> sampletext </p> 
+0

спасибо за этот ответ! Я изначально использовал rvest, но столкнулся с трудностями. Наверное, я просто не знаю, как правильно его использовать. Когда я попробовал этот метод по своим данным, я получил ошибку «Ошибка: имя d: 2qwt не соответствует XML-пространству имен» [202] '. Вы видели что-нибудь подобное раньше? – xyy

+0

Я не могу помочь, не видя соответствующую часть данных, но на самом деле 'readLines' - это плохой способ импорта HTML, что, скорее всего, будет проблемой. Вместо этого передайте 'read_html()' URL или путь к файлу для чтения данных непосредственно как HTML. Есть вероятность, что это на самом деле просто искаженный HTML, но убедитесь, что это не ваш процесс, прежде чем вы начнете искать сотни строк кода. – alistaire

1

Это базовое решение R. Два GREP операции обеспечивают запуск и остановку линию для пунктов к -administered функции mapply, чтобы свернуть их вместе с paste:

> txt <- scan(what="") 
1: "<P> sampletextsampletext" 
2: "sampletextsampletext</P>" 
3: "<P> sampletext" 
4: "sampletext" 
5: "sampletext</P>" 
6: "<P> sampletext </P>" 
7: 
Read 6 items 
> grep("<P>", txt) 
[1] 1 3 6 
> grep("</P>", txt) 
[1] 2 5 6 
> mapply(function(x,y) paste(txt[x:y], collapse=" "), grep("<P>", txt), grep("</P>", txt)) 
[1] "<P> sampletextsampletext sampletextsampletext</P>" 
[2] "<P> sampletext sampletext sampletext</P>"   
[3] "<P> sampletext </P>" 
Смежные вопросы