【问题标题】:In R : extract information in text sentence [closed]在 R 中:提取文本句子中的信息 [关闭]
【发布时间】:2017-01-26 13:42:35
【问题描述】:

我有一些文章的全文。我想提取一些信息(如年份或月份)来分析它。

并以文章文本的结构为例,

2016 年 12 月 4 日星期日,LENGTH:(正文长度),HEADLINE:( 文章标题),BYLINE:(记者姓名),BODY:(正文)

我将所有的文本一行一行地放在一篇文章中。(所以我认为可以将文章结构视为一个字符串。)

在这种格式下,如何提取 LENGTH、HEADLINE、BYLINE 值并制作数据框?

我认为如果正确使用正则表达式是可能的,但我不知道如何准确。

【问题讨论】:

  • 绝对是正则表达式,参见 ?regexpr 或 regexpr
  • 感谢您的评论!

标签: r split extract sentence


【解决方案1】:

首先以可重复的方式定义测试数据——我们使用了问题中显示的数据的两个实例。我们注意到棘手的部分是每条记录在问题中运行超过 1 行。

读入Lines——用真实数据替换textConnection(Lines),这是为了保持代码自包含,比如"myfile.txt"

然后第一个 sub 在每行的开头插入一个空格,第二个替换所有包含 LENGTH: 的行上的所有内容,包括 LENGTH: 和换行符、DATE:、日期和 LENGTH:gsub 在每个关键字之前插入一个换行符,paste 将其全部折叠成一个大的换行符分隔字符串。 strsplit再次拆分它,以便我们添加的换行符生效。

数据现在是 DCF 格式,因此我们可以使用 read.dcf 读取它。 DCF 格式用一个或多个空行分隔记录,并以字段名后跟冒号和空格后跟值开始每个字段。如果后续行缩进,则该值可以运行到多行,例如以空格开头。

这给出了一个包含 5 列的矩阵。最后一个sub 删除每个元素末尾的逗号,最后一个gsub 用空格替换换行符。

请注意,我们已将字段放在列中,这通常是在 R 中表示数据的方式,但如果您真的希望将其放在行中,请使用 t(dcf)

# test data

Lines <- "December 4, 2016 Sunday, LENGTH: 1070 words, HEADLINE: Korea presents new farm
development model globally, BYLINE: By Yoon Ja-young, BODY: ~~~
December 4, 2016 Sunday, LENGTH: 1070 words, HEADLINE: Korea presents new farm
development model globally, BYLINE: By Yoon Ja-young, BODY: ~~~"

# code

L0 <- readLines(textConnection(Lines))
L <- sub("^", " ", L0)
L <- sub("(.*) LENGTH:", "\nDATE: \\1 LENGTH:", L)
L <- gsub("(\\w+:)", "\n\\1", L)
L <- paste(L, collapse = "\n")
L <- unlist(strsplit(L, "\n"))
dcf <- read.dcf(textConnection(L))
dcf[] <- sub(",$", "", dcf)
dcf[] <- gsub("\n", " ", dcf)

这给出了以下 5 列字符矩阵:

> dcf

     DATE                      LENGTH      
[1,] "December 4, 2016 Sunday" "1070 words"
[2,] "December 4, 2016 Sunday" "1070 words"
     HEADLINE                                             BYLINE            
[1,] "Korea presents new farm development model globally" "By Yoon Ja-young"
[2,] "Korea presents new farm development model globally" "By Yoon Ja-young"
     BODY 
[1,] "~~~"
[2,] "~~~"

更新:添加日期输出。

【讨论】:

  • 按列比按行更有意义。很好的解决方案。
  • 通常在数据处理中,字段是列,而不是行。
【解决方案2】:

我希望下面的解决方案会有所帮助。我相信更有效的方法是可能的,请查看gsubgrepstringr


DF<-data.frame(do.call(rbind, strsplit(x, ",", fixed=TRUE)))
DF$X1 <- paste(DF$X1,DF$X2, sep = ",")    
new_df<-as.data.frame(lapply(DF, function(x) gsub(".*:", "", x)))
new_df<-subset(new_df, select = -X2)
colnames(new_df)<-c("Date","Length","Headline","ByLine","Other")
new_df

输出

                       Date      Length                                            Headline
1   December 4, 2016 Sunday  1070 words  Korea presents new farm development model globally
2 Noveember 10, 2016 Friday  1070 words  Korea presents new farm development model globally
             ByLine Other
1  By Yoon Ja-young   ~~~
2  By Yoon Ja-young   ~~~

数据

 x<- c("December 4, 2016 Sunday, LENGTH: 1070 words, HEADLINE: Korea
       presents new farm development model globally, BYLINE: By Yoon Ja-young, BODY: ~~~",
      "Noveember 10, 2016 Friday, LENGTH: 1070 words, HEADLINE: Korea 
       presents new farm development model globally, BYLINE: By Yoon Ja-young, BODY: ~~~")

更新:正如@G.Grothendieck 在 cmets 中提到的,将解决方案更改为将字段显示为列。

【讨论】:

    【解决方案3】:

    这可能是一个开始:使用strsplit 提取您需要的部分。这段代码有点乱,但可以:

    sentence <- "December 4, 2016 Sunday, LENGTH: 1070 words, HEADLINE: Korea presents new farm development model globally, BYLINE: By Yoon Ja-young"
    
    Date <- as.character(sapply(strsplit(sentence, "LENGTH"), "[[",1))
    Rows <- as.character(sapply(strsplit(sentence, "LENGTH"), "[[",2))
    Length <- gsub(":","", as.character(sapply(strsplit(Rows, ","), "[[",1)))
    Headline <- as.character(sapply(strsplit(as.character(sapply(strsplit(Rows, ","), "[[",2)), ":"), "[[",2))
    Byline <- as.character(sapply(strsplit(as.character(sapply(strsplit(Rows, ","), "[[",3)), ":"), "[[",2))
    

    然后收集数据框中的行:

      Df <- data.frame(Date, Length, Headline, Byline)  
    

    【讨论】:

      【解决方案4】:

      这是一个在基本 R 包中使用字符串拆分和一些正则表达式的答案。只要数据始终采用所示格式,它就可以工作。

      data <- "December 4, 2016 Sunday, LENGTH: 1070 words, HEADLINE: Korea presents new farm development model globally, BYLINE: By Yoon Ja-young, BODY: ~~~"
      
      textParse <- function(dat){
          tmp <- strsplit(dat, ', ')[[1]]
      
          time <- as.Date(paste(tmp[1:2], collapse = ' '), format="%B %d %Y")
      
          len <- strsplit(gsub(".*LENGTH: (\\d+)", "\\1", dat), " ")[[1]][1]
      
          headline <- paste(strsplit(tmp[4], ' ')[[1]][2:length(strsplit(tmp[4], ' ')[[1]])], collapse = ' ')
      
          byline <- paste(strsplit(tmp[5], ' ')[[1]][3:length(strsplit(tmp[5], ' ')[[1]])], collapse = ' ')
      
          body <- paste(strsplit(tmp[6], ' ')[[1]][2:length(strsplit(tmp[6], ' ')[[1]])], collapse = ' ')
      
          return(as.data.frame(cbind(time, len, headline, byline, body)))
      }
      
      textParse(data)
      

      输出:

       time   len                                            headline     byline
      1 17139 1070 Korea presents new farm development model globally Yoon Ja-young
        body
      1  ~~~
      

      编辑:请注意,R 中的时间表示为整数“自 1970-01-01 以来的天数”R: Date-time Conversion

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-22
        • 1970-01-01
        • 1970-01-01
        • 2010-12-28
        相关资源
        最近更新 更多