【问题标题】:Extracting specific data from nested list从嵌套列表中提取特定数据
【发布时间】:2025-12-19 05:05:11
【问题描述】:

我正在尝试从 IMDB 抓取 2019 年的电影。我正在从嵌套列表中提取导演的姓名。 现在,问题是导演的名字不是针对所有电影,而是针对少数电影,因此我需要在出现“导演:\n”一词的地方提取导演的名字。

嵌套列表如下:

[[1]]
[1] "Henry Cavill,Freya Allan,Anya Chalotra,Mimi Ndiweni\n"

[[2]]
[1] "\n"                                                          
[2] "Director:\nJ.J. Abrams"                                    
[3] "|"                                                           
[4] "Stars:\nCarrie Fisher,Mark Hamill,Adam Driver,Daisy Ridley\n"

[[3]]
[1] "Pedro Pascal,Carl Weathers,Rio Hackford,Gina Carano\n"

[[4]]
[1] "\n"                                                                       
[2] "Director:\nTom Hooper"                                                    
[3] "|"                                                                        
[4] "Stars:\nFrancesca Hayward,Taylor Swift,Laurie Davidson,Robbie Fairchild\n"

[[5]]
[1] "Guy Pearce,Andy Serkis,Stephen Graham,Joe Alwyn\n"

[[6]]
[1] "\n"                                                                   
[2] "Director:\nMichael Bay"                                              
[3] "|"                                                                    
[4] "Stars:\nRyan Reynolds,Mélanie Laurent,Manuel Garcia-Rulfo,Ben Hardy\n"

这里可以看到,导演的名字以另一种方式出现,但这只是为了举例。提前致谢。

预期输出:

directors_data NA,"J.J.艾布拉姆斯",NA,"迈克尔贝"

【问题讨论】:

  • 您能否使用dput 共享数据并显示给定示例的预期输出?我的意思是在没有“导演”一词的地方,您需要NA 还是完全忽略该条目?
  • 我想要 NA 以便最终数据帧没有行计数问题。
  • 为什么“Tom Hooper”不在所需的输出中?

标签: r list nested


【解决方案1】:

这是一个基本的 R 解决方案,您可以使用方法grep+gsub,或方法regmatches + gregexpr

假设你的data是一个列表lst,那么你可以试试下面的代码来提取导演的名字:

sapply(lst, function(x) ifelse(length(r <- grep("Director",x,value = T)),gsub("Director:\n","",r),NA))

sapply(lst, function(x) ifelse(length(r<-unlist(regmatches(x,gregexpr("(?<=Director:\n)(.*)",x,perl = T)))),r,NA))

【讨论】:

    【解决方案2】:

    您可以使用str_extract 提取字符串并使用map 循环遍历列表中的每个元素

    library(purrr)
    library(stringr)
    
    map_chr(list_df, ~{temp <- na.omit(str_extract(.x, "(?<=Director:\n)(.*)")); 
                       if(length(temp) > 0) temp else NA})
    
    #[1] NA            "J.J. Abrams" NA            "Tom Hooper" 
    

    数据

    由于您没有提供可重现的示例,我自己创建了一个。

    list_df <- list("Henry Cavill,Freya Allan,Anya Chalotra,Mimi Ndiweni\n", 
    c("\n", "Director:\nJ.J. Abrams", "|", "Stars:\nCarrie Fisher,Mark Hamill,Adam Driver,Daisy Ridley\n"
    ), "Pedro Pascal,Carl Weathers,Rio Hackford,Gina Carano\n", 
    c("\n", "Director:\nTom Hooper", "|", "Stars:\nFrancesca Hayward,Taylor Swift,Laurie Davidson,Robbie Fairchild\n"
    ))
    

    【讨论】:

      【解决方案3】:

      基础 R 解决方案:

      directors_data <- gsub("Director:\n", "",
      
                             unlist(Map(function(x){x[2]}, list_df)), fixed = TRUE)
      

      不使用 unlist 和使用 mapply not Map 的 Base R 解决方案:

      directors_data <- gsub(".*\\\n", "",
      
                             mapply(function(x){x[2]}, list_df, SIMPLIFY = TRUE))
      

      如果模式出现在每个列表元素的不同索引处,则基本 R 解决方案:

      directors_data <- gsub(".*\\\n", "",
      
                             mapply(function(x) {
      
                               ifelse(length(x[which(grepl("Director", x))]) > 0,
      
                                      x[which(grepl("Director", x))],
      
                                      NA)}, list_df, SIMPLIFY = TRUE))
      

      【讨论】: