【问题标题】:Concatenate multiples words each in separate row into one row using R使用R将每个单独行中的多个单词连接成一行
【发布时间】:2018-05-07 18:28:52
【问题描述】:

我有一个每行一个单词的数据框,但我想根据列 spk 和 id 的值使用 R 将其转换为每行的句子/段落。这是一个数据框示例:

id  word    spk
123 hi       1
123 how      1
123 are      1
123 you      1
123 good     2
123 thank    2
123 you      2
123 Anything 1
123 I        1
123 can      1
123 do       1
123 nothing  2
123 for      2
123 now      2
789 what     1
789 is       1
789 the      1
789 issue    1
789 there    2
789 is       2
789 no       2
789 issue    2
789 now      2
789 thank    1
789 you      1
789 for      1
789 contacting1
789 us       1

期望的输出

id  word                           spk
123 hi how are you                  1
123 good thank you                  2
123 Anything I can do               1
123 nothing for now                 2
789 what is the issue               1
789 there is no issue now           2
789 thank you for contacting us     1

任何帮助将不胜感激。谢谢

【问题讨论】:

  • 只是一个注释,在R concatenate(与c())中将单词组装成一个向量(如其他语言中的列表或一维数组),而paste() 将它们粘合在一起变成一个字符串(这就是你在这里所做的)
  • 假设数据框名称是 df。在保持每行 ID 的同时如何连接。注意:我能够将每个 id 下的单词连接到一个段落,将每个 id 下的所有单词连接成一个句子/段落。

标签: r concatenation


【解决方案1】:
require(data.table)
setDT(df)

df[, .(word = paste(word, collapse = ' ')
     , id   = unique(id)
     , spk  = unique(spk))
   , by = .(phrase = rleid(spk))]

#    phrase                        word  id spk
# 1:      1              hi how are you 123   1
# 2:      2              good thank you 123   2
# 3:      3           Anything I can do 123   1
# 4:      4             nothing for now 123   2
# 5:      5           what is the issue 789   1
# 6:      6       there is no issue now 789   2
# 7:      7 thank you for contacting us 789   1

在 tidyverse 中这是

df %>%
  mutate(phrase = data.table::rleid(spk)) %>%
  group_by(phrase) %>%
  summarise(id = unique(id),
            words = paste(word, collapse = " "))

【讨论】:

  • 我收到此错误:[.data.frame(df, , .(word = paste(word, collapse = " "), 中的错误:未使用的参数 (by = .(phrase = rleid("spk ")))
  • 你忘了运行setDT(df)
  • 我使用了 tidyverse 的建议,但我得到了这个:Column id must be length 1 (a summary value), not 2
  • 运行 setDT(df),但我得到了这个: setDT(df) 中的错误:由于绑定已锁定,无法通过引用将 'df' 转换为 data.table。 'df' 很可能驻留在已锁定以防止修改其变量绑定的包(或环境)中。尝试将对象复制到当前环境,例如:var
【解决方案2】:

这是一个tidyverse 方法,它也从data.table 包中借用了rleid:

library(tidyverse)

df <- 
structure(list(id = c(123L, 123L, 123L, 123L, 123L, 123L, 123L, 123L, 123L, 123L, 123L, 123L, 123L, 123L, 789L, 789L, 789L, 789L, 789L, 789L, 789L, 789L, 789L, 789L, 789L, 789L, 789L, 789L), 
               word = structure(c(8L, 9L, 2L, 21L, 7L, 16L, 21L, 1L, 10L, 3L, 5L, 14L, 6L, 15L, 20L, 11L, 17L, 12L, 18L, 11L, 13L, 12L, 15L, 16L, 21L, 6L, 4L, 19L), 
              .Label = c("Anything", "are", "can", "contacting", "do", "for", "good", "hi", "how", "I", "is", "issue", "no", "nothing", "now", "thank", "the", "there", "us", "what", "you"), class = "factor"), 
              spk = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L)), class = "data.frame", row.names = c(NA, -28L))

df %>%
  mutate(spk_num = data.table::rleid(spk)) %>%
  mutate(word = as.character(word)) %>%
  group_by(id, spk, spk_num) %>%
  nest() %>%
  mutate(words = map(data, unlist),
         words = map_chr(words, paste, collapse = " "))

# A tibble: 7 x 5
     id   spk spk_num data             words                      
  <int> <int>   <int> <list>           <chr>                      
1   123     1       1 <tibble [4 x 1]> hi how are you             
2   123     2       2 <tibble [3 x 1]> good thank you             
3   123     1       3 <tibble [4 x 1]> Anything I can do          
4   123     2       4 <tibble [3 x 1]> nothing for now            
5   789     1       5 <tibble [4 x 1]> what is the issue          
6   789     2       6 <tibble [5 x 1]> there is no issue now      
7   789     1       7 <tibble [5 x 1]> thank you for contacting us

概述:首先,创建一个spk_num 列,因为您想要的输出希望区分同一 id 内的扬声器。接下来,group_by 一切和nest 数据。最后,我们将在整个输出中映射 paste 与折叠,但您首先需要取消列出单词数据。

【讨论】:

  • 尝试了上面的代码,但我得到了这个: mutate_impl(.data, dots) 中的错误:列word 的长度必须为 87(行数)或 1,而不是 6
  • 确保word 不是一个因素。我已经更新了代码。
  • 还是一样:mutate_impl(.data, dots) 中的错误:列 word 的长度必须为 87(行数)或 1,而不是 6。
  • 仔细检查您的拼写?请注意,我有words not word - 我在答案中粘贴了原始df 的结构,它应该完全可以复制和粘贴。跨度>
  • 你在 mutate(words = map(data, unlist) 中使用的数据是什么?
【解决方案3】:

您可以使用带有函数 paste() 的 data.table 来执行此操作,方法是对行进行适当的分组。唯一的问题是您没有参考当前对话的哪个短语,因此首先您必须创建一个新列来指定这一点。

library(data.table)

#This function takes a vector of speakers, say, (1,1,1,2,2,1,1,2,2,2) and gives you which phrase of the conversation you're on (1,1,1,2,2,3,3,4,4,4)

class_phrase = function(spk){
  phrase = 1
  phrase_n = 1
  for(i in 2:length(spk)){
    if(spk[i] == spk[i-1])
      {phrase[i] = phrase[i-1]} else
      {phrase_n = phrase_n + 1
       phrase[i] = phrase_n}
  }
  return(phrase)
}

#Now you use this function with your data.table, grouping by id:

dt[, phrase := class_phrase(spk), by = id]

#Having a phrase number, you can just paste everything together by grouping your original data.table by id and phrase

dt[, .(word = paste(word, collapse = ' '), spk = unique(spk)), by = .(id, phrase)]

【讨论】:

    【解决方案4】:

    另一种dplyr 方法,假设您的word 列是一个字符向量:

    library(dplyr)
    
    df %>%
      mutate(group = cumsum(ifelse(df$spk != lag(df$spk, default = 0), 1, 0))) %>%
      group_by(id, group) %>%
      mutate(sentence = paste(word, collapse = " ")) %>%
      ungroup %>%
      select(-word, -group) %>%
      distinct() 
    
    # A tibble: 7 x 3
         id   spk sentence                   
      <int> <int> <chr>                      
    1   123     1 hi how are you             
    2   123     2 good thank you             
    3   123     1 Anything I can do          
    4   123     2 nothing for now            
    5   789     1 what is the issue          
    6   789     2 there is no issue now      
    7   789     1 thank you for contacting us
    

    【讨论】:

      【解决方案5】:

      这是一个基本版本:

      df$i <-  cumsum(c(FALSE,!!diff(df$spk)))
      aggregate(word ~ id + spk + i,df,paste,collapse= " ")[-3]
      #    id spk                        word
      # 1 123   1              hi how are you
      # 2 123   2              good thank you
      # 3 123   1           Anything I can do
      # 4 123   2             nothing for now
      # 5 789   1           what is the issue
      # 6 789   2       there is no issue now
      # 7 789   1 thank you for contacting us
      

      【讨论】:

        猜你喜欢
        • 2012-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-29
        • 2020-05-22
        • 1970-01-01
        相关资源
        最近更新 更多