【问题标题】:How to Split Chr data based on | and make new entry for every word如何根据 | 拆分 Chr 数据并为每个单词创建新条目
【发布时间】:2023-03-15 19:59:01
【问题描述】:

我有其中一列是流派(chr)的数据,值就像“戏剧|音乐|犯罪”,我需要拆分这些数据并需要为每个条目创建新行,就像那里的这个值一样是 3 个值,所以我需要在该数据框中的所有列中创建三个条目。

   imdbId <- "tt0118578"
   title <-"Albela"
   releaseYear<- 2010
   releaseDate  <- "2-12-2010"
   genre <- "Adventure | Drama | Musical"
   writers <- "Ashutosh Gowariker (story) | Ashutosh Gowariker (screenplay) | 
   Kumar Dave (screenplay) | Sanjay Dayma (screenplay) | K.P. Saxena 
   (dialogue)"
   actors <-"Aamir Khan | Gracy Singh | Rachel Shelley | Paul Blackthorne"
   directors<-"Ashutosh Gowariker"
   sequel <-"No"
   hitFlop <-2
   df <- data.frame(imdbId, title,  releaseYear,    releaseDate,    genre,   
   writers, actors, directors,  sequel, hitFlop
    , stringsAsFactors=FALSE)**

这是现在数据框的 str,我需要拆分数据并根据单一类型值为每部电影制作唯一条目。

【问题讨论】:

  • 分享您的研究对每个人都有帮助。告诉我们您尝试了什么以及为什么它不能满足您的需求。这表明您已经花时间尝试帮助自己,它使我们免于重复明显的答案,最重要的是它可以帮助您获得更具体和相关的答案!另见:How to Ask
  • 除了@RalfStubner 所说的之外,您能否提供一些您尝试过的代码以及您正在使用的库?这将有助于我们更快地给您答复。
  • 为什么第二部“冒险剧”应该只有剧情???
  • 我是 R 新手,在 Stackoverflow 上也是,我尝试了一些东西,BollywoodMovieDetail %>% separate(BollywoodMovieDetail$genre, c("genre_1", "genre_2", "genre_3"), "| ", extra = "merge"),虽然它会将数据分离到 3 个不同的列中。
  • 我什至不确定您的数据框是什么样的?你能把你的数据转换成数据框然后显示吗

标签: r database dataframe


【解决方案1】:

这样的事情可能会奏效:

数据:

multiChar<-
"tt0169102
Lagaan: Once Upon a Time in India
2001
08 May 2002
Adventure | Drama | Musical
Ashutosh Gowariker (story) | Ashutosh Gowariker (screenplay) | Kumar Dave (screenplay) | Sanjay Dayma (screenplay) | K.P. Saxena (dialogue)
Aamir Khan | Gracy Singh | Rachel Shelley | Paul Blackthorne
Ashutosh Gowariker
0
6"

代码:

library(magrittr)
patterni <- "(?i)(?<=\\n).*(adventure|drama|musical)(\\s+?(\\|)?\\s+?).*(?=\\n)"

getGenres<- stringr::str_extract(multiChar, patterni) %>%
    str_split("\\|",simplify = T) %>% c %>% trimws

result <- purrr::map(getGenres,~sub(patterni,.,multiChar,perl=T))

结果:

lapply(result,cat)

请注意:

你可能必须想出一个更精确的模式patterni

这里需要第 5 行(流派行)。如果你的流派总是在第 5 行,那就是你的模式。

patterni <- "^(.*?\\n){4}.*(?=\\n)"
getGenres<- stringr::str_extract(multiChar, patterni) %>% sub(".*\\n","",.) %>%
    str_split("\\|",simplify = T) %>% c %>% trimws

【讨论】:

  • 谢谢安德烈,是的,它确实适用于这种情况,但我有大约 1880 行的数据集,在每一行中,我们有不同数量的流派值,用 | 分隔。但是非常感谢您的努力。
  • 最后看我的代码。我不能给你一个适合所有数据的解决方案! (因为我不知道你的数据,2需要很多时间)但这应该会引导你找到解决方案。
【解决方案2】:

回答一个问题很容易......如果问题的框架很好。没有提供代码,所以让我们假设一个数据框:

title <- "Lagaan: Once Upon a Time in India"
year <- 2001
genre <- "Adventure | Drama | Musical"
df <- data.frame(title, year, genre, stringsAsFactors=FALSE)

根据需要添加或复制尽可能多的行。然后根据需要替换流派列中的值。

对于流派名称的单个向量:

genres <- strsplit(df$genre, " \\| ")[[1]]

对于流派名称的向量列表:

genres <- strsplit(df$genre, " \\| ")

【讨论】:

  • 是的,我的错,但请耐心等待,我会在未来几天改进如何提出问题,以便所有人都清楚。
  • 我已经编辑了这个问题,看看它可能会有所帮助。
  • 深盘树,SO的目的是回答具体的代码问题,而不是提出开发问题让别人为你开发。请在发布之前运行您的代码。提供的代码 sn-p 没有运行。
  • (1) 以** 终止行会引发 EOF 错误。 (2) 在某些情况下,以, 结尾的行可以在下一行继续。行不能以, 开头。 (3) writers 字符串有一个嵌入的 CR/LF;你打算这样做吗?
【解决方案3】:

我创建了一个函数,它使用 stringr 来拆分列,给定生成列的模式和名称前缀。

    **split_into_multiple <- function(column, pattern = ", ", into_prefix){
    cols <- str_split_fixed(column, pattern, n = Inf)
    # Sub out the ""'s returned by filling the matrix to the right, with NAs which 
    are useful
    cols[which(cols == "")] <- NA
    cols <- as.tibble(cols)
    # name the 'cols' tibble as 'into_prefix_1', 'into_prefix_2', ..., 
    'into_prefix_m' 
    # where m = # columns of 'cols'
    m <- dim(cols)[2]
    names(cols) <- paste(into_prefix, 1:m, sep = "_")
    return(cols)
    }**

然后我们可以在 dplyr 管道中使用 split_into_multiple,如下所示:

    **after <- BollywoodMovieDetail %>% 
    bind_cols(split_into_multiple(.$genre,"\\|", "genre")) %>% 
    # selecting those that start with 'genre_' will remove the original 'genre' column
    select(imdbId, starts_with("genre_"))
    > after
    # A tibble: 1,284 x 4
    imdbId    genre_1      genre_2     genre_3   
    <chr>     <chr>        <chr>       <chr>     
    1 tt0118578 Romance      NA          NA        
    2 tt0169102 "Adventure " " Drama "   " Musical"
    3 tt0187279 "Action "    " Comedy"   NA        
    4 tt0222024 "Drama "     " Romance"  NA        

    # ... with 1,274 more rows**

然后我们就可以使用gather来收拾...

    **> after %>% 
    +     gather(key, val, -imdbId, na.rm = T)
    A tibble: 2,826 x 3
   imdbId    key     val         
  * <chr>     <chr>   <chr>       
  1 tt0118578 genre_1 Romance     
  2 tt0169102 genre_1 "Adventure "
  3 tt0187279 genre_1 "Action "   
  4 tt0222024 genre_1 "Drama "    
  5 tt0227194 genre_1 "Action "   

  # ... with 2,816 more rows**

【讨论】:

    猜你喜欢
    • 2020-07-24
    • 2020-03-29
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 2019-01-01
    • 2018-06-07
    相关资源
    最近更新 更多