如何有效地从 R 数据框中的一列中的另一列中删除文本?

问题描述 投票:0回答:1

我尝试过 apply (apply & lapply) 和 foreach + doParallel,但我认为我对这两个概念缺乏完整的理解,无法使它们发挥作用。

最终,我想查看 Sub_ID(以及 Sub_Sub_ID)列表并将它们从“文本”列中删除。 Text 列按原样出现,由某人手动输入(它是文本注释),因此 Sub_ID 和 Sub_Sub_ID 将按任意顺序排列,并且可能不会全部都在 Text 列中;因此,我不能依赖整个列表的完全匹配。 Sub_ID 和 Sub_Sub_ID 列可以旋转为每行 1 个,而不是组合并用逗号分隔,但我发现将它们全部拉入一行更有意义。

下面是我能够想出的,它按预期工作,但它很慢WWWW(实际数据有 220K+ 行)。

样本数据:

身份证 文字 子_ID 子_子_ID
1 一些文本 sub_id 1,2,3 和 sub_sub_id 1,2,3 3,2,1 1,2,3
2 一些文本 sub_id 1,2,3 和 sub_sub_id 1,2,3 1,2,3 2,3,1
3 一些文本 sub_id 4,5 和 sub_sub_id 1,2,3 4,5 1,2,3
4 一些文本 sub_id 4 和 sub_sub_id 1,2 4 2,1
5 一些文本 sub_id 5 和 sub_sub_id 3 5 3

当前for循环:

library(stringr)

for (r in 1:nrow(sample_data)) {
  for (Sub_ID in unlist(str_split(sample_data[r]$Sub_ID,','))) {
    sample_data[r]$Text <- str_replace_all(sample_data[r]$Text,Sub_ID,'')
  }
  for (Sub_Sub_ID in unlist(str_split(temp[r]$Sub_Sub_ID,','))) {
    sample_data[r]$Text <- str_replace_all(sample_data[r]$Text,Sub_Sub_ID,'')
  }
}

上表中第 1 行的所需输出: 文字 =

some text sub_id and sub_sub_id

有没有办法让它更快?我已经尝试过 apply 和 foreach 如前所述,但我无法让这两个工作。

通过 apply,我真的很难处理相互依赖的列(因为我正在查看一列以查找要从另一列删除的值)。我收到了几条不同的错误消息,似乎我无法使其工作/对于申请来说太复杂了。

foreach 给了我以下非常有用的错误消息:

{ 中的错误:任务 8 失败 - “替换有 0 行,数据有 213474”

我的最终目标是在 Tableau 中为词云创建一个数据源,并且我正在尝试删除 Sub_ID 和 Sub_Sub_ID,因为它们将成为词云中最大的词,因为它们在每个评论中都会使用他们在;然而,他们并没有真正指导任何决定/帮助人们。

r apply
1个回答
1
投票

从这些循环看来,空格和标点符号在这里不起作用,所以这是一种肮脏的正则表达式方法,我们只需粘贴

Sub_ID*
列来形成正则表达式并用 220k 行测试
str_remove_all()

library(stringr)
sample_data <- tibble::tribble(
  ~ID,                                         ~Text, ~Sub_ID, ~Sub_Sub_ID,
   1L, "some text sub_id 1,2,3 and sub_sub_id 1,2,3", "3,2,1",     "1,2,3",
   2L, "some text sub_id 1,2,3 and sub_sub_id 1,2,3", "1,2,3",     "2,3,1",
   3L,   "some text sub_id 4,5 and sub_sub_id 1,2,3",   "4,5",     "1,2,3",
   4L,       "some text sub_id 4 and sub_sub_id 1,2",     "4",       "2,1",
   5L,         "some text sub_id 5 and sub_sub_id 3",     "5",         "3"
  )

# generate 220k rows 
sample_220k <- rep(list(sample_data), 220000/nrow(sample_data)) |> do.call(rbind, args = _)
str(sample_220k)
#> tibble [220,000 × 4] (S3: tbl_df/tbl/data.frame)
#>  $ ID        : int [1:220000] 1 2 3 4 5 1 2 3 4 5 ...
#>  $ Text      : chr [1:220000] "some text sub_id 1,2,3 and sub_sub_id 1,2,3" "some text sub_id 1,2,3 and sub_sub_id 1,2,3" "some text sub_id 4,5 and sub_sub_id 1,2,3" "some text sub_id 4 and sub_sub_id 1,2" ...
#>  $ Sub_ID    : chr [1:220000] "3,2,1" "1,2,3" "4,5" "4" ...
#>  $ Sub_Sub_ID: chr [1:220000] "1,2,3" "2,3,1" "1,2,3" "2,1" ...

tictoc::tic()
sample_220k$Text <- str_remove_all(sample_220k$Text, str_glue("[{sample_220k$Sub_ID},{sample_220k$Sub_Sub_ID}]"))
tictoc::toc()
#> 1.44 sec elapsed

head(sample_220k)
#> # A tibble: 6 × 4
#>      ID Text                                Sub_ID Sub_Sub_ID
#>   <int> <chr>                               <chr>  <chr>     
#> 1     1 "some text sub_id  and sub_sub_id " 3,2,1  1,2,3     
#> 2     2 "some text sub_id  and sub_sub_id " 1,2,3  2,3,1     
#> 3     3 "some text sub_id  and sub_sub_id " 4,5    1,2,3     
#> 4     4 "some text sub_id  and sub_sub_id " 4      2,1       
#> 5     5 "some text sub_id  and sub_sub_id " 5      3         
#> 6     1 "some text sub_id  and sub_sub_id " 3,2,1  1,2,3

创建于 2023-10-31,使用 reprex v2.0.2

© www.soinside.com 2019 - 2024. All rights reserved.