【问题标题】:How to match list of characters with partial strings in R?如何将字符列表与R中的部分字符串匹配?
【发布时间】:2020-05-02 14:37:49
【问题描述】:

我正在分析 RePEc 数据库中的 ID。每个 ID 都匹配一个唯一的出版物,有时出版物是相互链接的,因为它们是彼此的不同版本(例如,工作论文变成了期刊文章)。我有一个包含大约 250,000 个条目的数据库,这些条目在一列中显示主要 ID,然后在另一列中显示前一个或备用 ID。它看起来像这样:

df$repec_id <– c("RePEc:cid:wgha:353", "RePEc:hgd:wpfacu:350","RePEc:cpi:dynxce:050")
df$alt_repec_id <– c("RePEc:sii:giihdizi:heidwg06-2019|RePEc:azi:cusiihdizi:gdhs06-2019", "RePEc:tqu:vishdizi:d8z7-200x", "RePEc:aus:cecips:15_59|RePEc:sga:leciam:c8wc0z888s|RePEc:cpi:dynxce:050", "RePEc:cid:wgha:353|RePEc:hgd:wpfacu:350")

我想找出repec_id 列中的哪些ID 也出现在alt_repec_id 列中,并创建一个只有符合此条件的行的数据框。我试图在“|”处拆分并像这样使用%in% 函数:

df <- separate_rows(df, alt_repec_id, sep = "\\|") 
df1 <- df1[trimws(df$alt_repec_id) %in% trimws(df$repec_id), ]
df1<- data.frame(df1)
df1 <- na.omit(df1)
df1 <- df1[!duplicated(df1$repec_id),]

它有效,但我担心通过根据repec_id 列中的值消除重复行,我会随机消除匹配项。那正确吗?

最终,我想要一个只包含 repec_id 列中的字符串与 alt_repec_id 列中的部分字符串匹配的值的数据框。使用上面的示例,我想要以下结果:

df$repec_id <– c("RePEc:cpi:dynxce:050")
df$alt_repec_id <– c("RePEc:aus:cecips:15_59|RePEc:sga:leciam:c8wc0z888s|RePEc:cpi:dynxce:050")

有人能解决我的问题吗?提前感谢您的帮助!

【问题讨论】:

  • 你尝试过内部连接吗?
  • 在您上面提供的示例中,3 行中的任何一行是否符合您要查找的条件?
  • 没有一个匹配。如果他们这样做会更容易理解吗?另外,我还没有尝试过内部连接。我将如何在这里使用它?谢谢你们的帮助!
  • 查看新示例和所需输出

标签: r


【解决方案1】:

尝试使用stringr 中的str_detect() 来确定@​​987654323@ 是否存在于较大的alt_repec_id 字符串中。

然后filter() 直到找到它的位置。这没有按预期返回,请尝试查看并发布一些 found_match == FALSE 但预期匹配的示例。

library(stringr)
library(dplyr)

df %>%
  mutate(found_match = str_detect(alt_repec_id, repec_id)) %>% 
  filter(found_match == TRUE)

【讨论】:

  • 嘿,谢谢。刚试了一下。不幸的是,结果很差(一个有 23 行的 df。它应该是大约 20,000)。难道是因为df$alt_repec_id中的很多id都是用“|”隔开的?
  • 这可能是一些事情。我会提出别的建议。分隔符应该不是问题。至少它跑得很快!发布更多数据不会受到伤害。这适用于示例。
  • 感谢您的帮助!我现在将发布更多数据。
  • 这很相似,但可以帮助您定位问题记录。
【解决方案2】:

这是使用grepl() + apply() + subset() 的基本 R 解决方案

dfout <- subset(df,apply(df, 1, function(v) grepl(v[1],v[2])))

这样

> dfout
              repec_id                                                            alt_repec_id
3 RePEc:cpi:dynxce:050 RePEc:aus:cecips:15_59|RePEc:sga:leciam:c8wc0z888s|RePEc:cpi:dynxce:050

数据

df <- structure(list(repec_id = structure(c(1L, 3L, 2L), .Label = c("RePEc:cid:wgha:353", 
"RePEc:cpi:dynxce:050", "RePEc:hgd:wpfacu:350"), class = "factor"), 
    alt_repec_id = structure(c(2L, 3L, 1L), .Label = c("RePEc:aus:cecips:15_59|RePEc:sga:leciam:c8wc0z888s|RePEc:cpi:dynxce:050", 
    "RePEc:sii:giihdizi:heidwg06-2019|RePEc:azi:cusiihdizi:gdhs06-2019", 
    "RePEc:tqu:vishdizi:d8z7-200x"), class = "factor")), class = "data.frame", row.names = c(NA, 
-3L))

【讨论】:

  • 嘿,第一个'1'在这里代表什么?这是第一列还是新的 df?
  • @Oliver 1 表示逐行应用函数
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-24
  • 2013-03-07
相关资源
最近更新 更多