Проблемы при извлечении первой и последней строки из строк текста, разделенных символом «>» в ​​кадре данных - PullRequest
0 голосов
/ 08 июня 2018

У меня есть датафрейм, который выглядит следующим образом:

 DF$Lst 
 [1] "Some text > in > a string"
     "Another > text in > another > set of string"  
     "This is only > One text"
     "NA"
     ..... so forth

Если вы заметили это, у каждой строки есть текст, который разделен '>'

Я хочу создать 'Два новых столбца, которые должны иметь только первую и последнюю строку, например:

  Text                                         Col1         Col2
  Some text > in > a string                    Some text    a string
  Another > text in > another > set of string  Another      set of string

Я пытался с помощью функции:

substrRight <- function(x, n){
  substr(x, nchar(x)-n+1, nchar(x))
}

substrRight(x, 6)

Но я думаю, что это неправильный подход.Потому что вышеуказанная функция не помогает.Можем ли мы решить проблему лучше?

Ответы [ 2 ]

0 голосов
/ 08 июня 2018

Базовая версия R:

text=DF$Lst# Will assume this is given
read.table(text=sub(">.*>",">",text),sep=">")
          V1             V2
1 Some text        a string
2   Another   set of string


cbind(text,read.table(text=sub(">.*>",">",text),sep=">"))
                                         text         V1             V2
1                   Some text > in > a string Some text        a string
2 Another > text in > another > set of string   Another   set of string

Другой базовый подход R:

data.frame(do.call(rbind,regmatches(text,regexec("(.*)>.*>(.*)",text))))
                                           X1                 X2             X3
1                   Some text > in > a string         Some text        a string
2 Another > text in > another > set of string Another > text in   set of string

РЕДАКТИРОВАТЬ:

read.table(text=sub("(^.*?)>(?:.*>)*(.*$)","\\1>\\2",text),sep=">",fill = T,na.strings = "")
             V1             V2
1    Some text        a string
2      Another   set of string
3 This is only        One text
4            NA           <NA>

или вы можете сделать:

read.table(text=sub("(^[^>]*).*?([^>]*$)","\\1>\\2",text),sep=">",fill = T,na.strings = "")
             V1             V2
1    Some text        a string
2      Another   set of string
3 This is only        One text
4          <NA>             NA

Использование separate

 separate(data.frame(text),text,c("col1","col2"),"((?:>.*)>|>)",fill="right" )
           col1           col2
1    Some text        a string
2      Another   set of string
3 This is only        One text
4            NA           <NA>
0 голосов
/ 08 июня 2018

Мы можем использовать extract из tidyr

library(tidyverse)
DF %>% 
 extract(Text, into = c('Col1', 'Col2'), '^([^>]+) >.* > ([^>]+)$', 
       remove = FALSE)
#                                       Text      Col1          Col2
#1                   Some text > in > a string Some text      a string
#2 Another > text in > another > set of string   Another set of string

Или с base R, split в >, а затем получить первый и последний элемент

DF[c('Col1', 'Col2')] <- t(sapply(strsplit(DF$Text, " > "),
             function(x) c(x[1], x[length(x)])))

Обновление

В обновленном наборе данных 'DF3' NAs являются символьными строками.Мы можем преобразовать его в реальные NA

is.na(DF3$Text) <- DF3$Text == "NA"
DF3[c('Col1', 'Col2')] <- t(sapply(strsplit(DF3$Text, " > "),
       function(x) c(x[1], x[length(x)])))
DF3
#                                         Text      Col1          Col2
#1                   Some text > in > a string Some text      a string
#2 Another > text in > another > set of string   Another set of string
#3                               This > is one      This        is one
#4                                        <NA>      <NA>          <NA>

или аналогично шаблону @ Onyambu

 DF3 %>%
   extract(Text, into = c("Col1", "Col2"), 
               "^([^>]*)>(?:.*>)?([^>]*)$", remove = FALSE)
 #                                       Text       Col1           Col2
 #1                   Some text > in > a string Some text        a string
 #2 Another > text in > another > set of string   Another   set of string
 #3                               This > is one      This          is one
 #4                                        <NA>       <NA>           <NA>

data

DF <- structure(list(Text = c("Some text > in > a string", 
 "Another > text in > another > set of string"
)), .Names = "Text", row.names = c(NA, -2L), class = "data.frame")   



DF3 <- structure(list(Text = c("Some text > in > a string",
"Another > text in > another > set of string", "This > is one", "NA")), 
 .Names = "Text", row.names = c(NA, -4L), class = "data.frame")
...