【问题标题】:Transpose every 4 rows into 4 individual columns将每 4 行转置为 4 个单独的列
【发布时间】:2019-02-17 05:35:40
【问题描述】:

我正在尝试使用以下循环从 IMDB 中抓取日期、标题和评论:

   library(rvest)
   library(dplyr)
   library(stringr)
   library(tidyverse)

   ID <- 4633694

data <- lapply(paste0('http://www.imdb.com/title/tt', ID, '/reviews?filter=prolific', 1:20),
                   function(url){
                     url %>% read_html() %>% 
                       html_nodes(".review-date,.rating-other-user-rating,.title,.show-more__control") %>% 
                       html_text() %>%
                       gsub('[\r\n\t]', '', .)
                   })

它提供了价值 20 页的评论数据,格式如下,重复相同的模式:

   col1
1 10/10
2 If this was..
3 14 December 2018
4 I have to say, and no...
5
6
7 10/10
8 Stan Lee Is Smiling Right Now...
9 17 December 2018
10 A movie worthy of...
11
12
13 10/10
14 the most visually stunning film I've ever seen...
15 20 December 2018
16 There's hardly anything... 
17.
18.

我想知道是否有办法将每 4 行转换为单独的列,以便每个属性在适当的列中对齐,如下所示:

         Date          Rating     Title            Review
1. 14 December 2018    10/10    If this was..    I have to...
2. 17 December 2018    10/10   Stan Lee Is...    A movie worthy...
3. 20 December 2018    10/10  the most visually.. There's hardly anything...

【问题讨论】:

    标签: r list web-scraping transpose rvest


    【解决方案1】:
    text_data = gsub('\\b(\\d+/\\d+)\\b','\n\\1',paste(grep('\\w',x$col1,value = TRUE),collapse = ':')) 
    
    read.csv(text=text_data,h=F,sep=":",strip.white = T,fill=T,stringsAsFactors = F)
         V1                                                V2               V3                         V4 V5
    1 10/10                                     If this was.. 14 December 2018   I have to say, and no... NA
    2 10/10                  Stan Lee Is Smiling Right Now... 17 December 2018       A movie worthy of... NA
    3 10/10 the most visually stunning film I've ever seen... 20 December 2018 There's hardly anything... NA
    

    【讨论】:

      【解决方案2】:

      这是一种方法。

      数据:

      x <- read.csv2(header=TRUE, stringsAsFactors=FALSE, text="
      col1
      10/10
      If this was..
      14 December 2018
      I have to say, and no...
      
      
      10/10
      Stan Lee Is Smiling Right Now...
      17 December 2018
      A movie worthy of...
      
      
      10/10
      the most visually stunning film I've ever seen...
      20 December 2018
      There's hardly anything... 
      .
      .")
      

      首先,我们“找到”每一行,在这种情况下,它看起来像一个日期。请注意,您可能希望/需要微调此正则表达式,以尽量减少误报和误报。

      ind <- grep("^[0-9]+/[0-9]+", x$col1)
      x$col1[ind]
      # [1] "10/10" "10/10" "10/10"
      

      最后一行被放入ind 每个块的第一行的索引中。

      从这里,让我们提取每个块直到下一个块开始的地方(减 1),直到帧列的末尾:

      y <- Map(function(a,b) x$col[a:b], ind, c(ind[-1], nrow(x)))
      str(y)
      # List of 3
      #  $ : chr [1:5] "10/10" "If this was.." "14 December 2018" "I have to say, and no..." ...
      #  $ : chr [1:5] "10/10" "Stan Lee Is Smiling Right Now..." "17 December 2018" "A movie worthy of..." ...
      #  $ : chr [1:6] "10/10" "the most visually stunning film I've ever seen..." "20 December 2018" "There's hardly anything... " ...
      

      我们可以尝试向前跳(到下面的do.call),但它会遇到问题,因为我们的向量大小不同。我们可以通过将它们的长度设置为最长向量的长度来轻松解决这个问题。这是一个技巧:

      z <- lapply(y, `length<-`, max(lengths(y)))
      str(z)
      # List of 3
      #  $ : chr [1:6] "10/10" "If this was.." "14 December 2018" "I have to say, and no..." ...
      #  $ : chr [1:6] "10/10" "Stan Lee Is Smiling Right Now..." "17 December 2018" "A movie worthy of..." ...
      #  $ : chr [1:6] "10/10" "the most visually stunning film I've ever seen..." "20 December 2018" "There's hardly anything... " ...
      

      最后一步:

      setNames(do.call("rbind.data.frame", c(z, stringsAsFactors=FALSE)),
               letters[seq_len(length(z[[1]]))])
      #       a                                                 b                c
      # 1 10/10                                     If this was.. 14 December 2018
      # 2 10/10                  Stan Lee Is Smiling Right Now... 17 December 2018
      # 3 10/10 the most visually stunning film I've ever seen... 20 December 2018
      #                             d     e    f
      # 1    I have to say, and no... 10/10 <NA>
      # 2        A movie worthy of... 10/10 <NA>
      # 3 There's hardly anything...      .    .
      

      【讨论】:

      • 为什么不data.frame(matrix(trimws(x$col1),ncol = 6,byrow = T),stringsAsFactors = F)
      • 如果每个块的行数始终相同,则可以使用。在问题中提供的数据中,事实并非如此。 (我欣然承认,样本数据不太可能是“真实的”,因此不具代表性。)
      • OP 说模式在重复。我想这可能有更多的意义
      猜你喜欢
      • 2018-06-25
      • 2022-11-23
      • 2021-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-11
      • 1970-01-01
      相关资源
      最近更新 更多