【问题标题】:Look for word in sentence with R, if not there: drop row用 R 查找句子中的单词,如果没有的话:drop row
【发布时间】:2015-07-26 08:58:44
【问题描述】:

前段时间我发布了a question concerning the same project。我将复制粘贴该问题中的一些信息,以明确发生了什么。

我必须遍历目录中的所有文件,并且遍历每个文件的每一行。从这些行中,我提取了构建数据框所需的数据。每个文件名都是这样的。

airbag.WS-U-E-A.lst

. 是分隔符,.lst 是扩展名(可作为文本读取)。

每个文件每行包含数据,如

adapter.WR-P-P-F.lst

/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-F0000026.data.ids.xml:  <sentence>Een aanpassingseenheid ( adapter ) , aangebracht in een behuizing voornamelijk bestaande uit in- en uitvoereenheden , een koppeleenheid , een geheugeneenheid , een besturingseenheid ( met actieve en passieve elementen en monolitische geïntegreerde schakelingen ) en een elektrische voedingseenheid . &gt;</sentence>
/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-F0000026.data.ids.xml:  <sentence>ID=&quot;1&quot;&gt;Het toestel ( adapter ) draagt zorg voor de overbrenging van gegevens , met een snelheid van 10 Mbps ( megabits per seconde ) , tussen meerdere automatische gegevensverwerkende machines in een digitaal netwerk . &quot; &gt;</sentence>
/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-F0000034.data.ids.xml:  <sentence>Overwegende dat deze sensoren niet zijn ontworpen op de installatie van een gepantserde kabel ; dat de mogelijkheid moet worden geboden dat de gepantserde kabel niet verplicht wordt gesteld voor de aansluiting tussen de sensor en de adapter , maar alleen van de adapter naar het controleapparaat ; dat het bijgevolg noodzakelijk is de verordening dienovereenkomstig te wijzigen ;</sentence>

安全气囊.WS-U-E-A.lst

/home/nobackup/SONAR/COMPACT/WR-U-E-A/WR-U-E-A0000075.data.ids.xml:  <sentence>ja voor den airbag op te pompen eh :p</sentence>
/home/nobackup/SONAR/COMPACT/WR-U-E-A/WR-U-E-A0000129.data.ids.xml:  <sentence>Dobby , als ze valt heeft ze dan wel al ne airbag hee</sentence>

我的目标是制作一个如下所示的数据框:

filename             | word | component | leftContext
-------------------------------------------------------------------------------------
adapter.WR-P-P-F.lst  adapter  WR-P-P-F    Een aanpassingseenheid (
adapter.WR-P-P-F.lst  adapter  WR-P-P-F    ID=&quot;1&quot;&gt;Het toestel (
adapter.WR-P-P-F.lst  adapter  WR-P-P-F    [...] tussen de sensor en de
airbag.WS-U-E-A.lst   airbag   WS-U-E-A    ja voor den
airbag.WS-U-E-A.lst   airbag   WS-U-E-A    Dobby , als ze valt heeft ze dan wel al ne
  • fileName:循环遍历文件并列出所有文件名

    files <- list.files(pattern="*.lst", full.names=T, recursive=FALSE)
    d <- data.frame(fileName = unname(sapply(files, basename)), stringsAsFactors = FALSE)
    
  • 单词:从文件名中提取:

    d$word <- gsub("\\..+", "", d$fileName, perl=TRUE)
    
  • 组件:从文件名中提取:

    d$component <- gsub("^[^.]+.", "", d$fileName, perl=TRUE)
    d$component <- gsub(".lst$", "", d$component, perl=TRUE)
    
  • leftContext:首先获取句子,然后提取左侧上下文。 See this question.

    # New frame, creates e$sentence which holds the sentence
    e <- do.call(rbind, lapply(files, function(x) {
        data.frame(fileName = x, sentence = readLines(x, encoding="UTF-8"), stringsAsFactors = FALSE)
    }))
    # Merge two frames
    df <- merge(d, e, by="fileName", all=TRUE)
    # Get contexts
    contexts <- strsplit(df$sentence, df$node)
    df$leftContext <- sapply(contexts, `[`, 1)
    

那里。现在我得到了我想要的结果!和我上面贴的一样。 但是,问题就在这里。

在我的项目中,我只想要实际包含 word 的句子。假设我们将word 定义为适配器,但我只有以下句子:

Ik zie de adapters niet
Waar is de adapter-aansluiting?
Een aanpassing aan de adapter

输出应该是:

filename                   | word  | component       | leftContext
-------------------------------------------------------------------------------------
adapter.some-component.lst  adapter  some-component    Een aanpassing aan de 

因为第一个句子不匹配(它包含结尾的s),第二个也不匹配(它包含额外的-aansluiting)。所以我需要的是一个 exact 单词匹配,但它应该不区分大小写。

我想我需要在流程的早期删除不包含该单词的行。可能是我们定义e 的地方。我怎么看:

e <- do.call(rbind, lapply(files, function(x) {
    # if SENTENCE contains WORD (case insensitive)
    data.frame(fileName = x, sentence = readLines(x, encoding="UTF-8"), stringsAsFactors = FALSE)
    # endif
}))

但公平地说,我不知道如何应用它。以下是一些示例数据:

aids.WR-P-P-D.lst

/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-D0000026.data.ids.xml:  <sentence>Het aids-probleem ontstaat door mensen zonder vaste partner, legt de speciale editie uit.</sentence>
/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-D0000036.data.ids.xml:  <sentence>Vorig jaar stierven 3 miljoen mensen aan aids en raakten er 5 miljoen besmet met hiv.</sentence>

aids.WR-P-P-E.lst

/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-E0000002.data.ids.xml:  <sentence>Zuid-Afrika heeft de meeste aids-gevallen ter wereld.</sentence>
/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-E0000126.data.ids.xml:  <sentence>Aids is geen pretje.</sentence>

aids.WR-P-P-G.lst

/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-G0000134.data.ids.xml:  <sentence>Veilige seks kan aids voorkomen.</sentence>
/home/nobackup/SONAR/COMPACT/WR-P-P-F/WR-P-P-G0000288.data.ids.xml:  <sentence>Want naarmate de aids-epidemie in Zuid-Afrika en omliggende landen groeit, zoeken miljoenen besmette mensen steeds wanhopiger naar een geneesmiddel.</sentence>

预期输出:

filename          | word | component  | leftContext
-------------------------------------------------------------------------------------
aids.WR-P-P-D.lst  aids   WR-P-P-D      Vorig jaar stierven 3 miljoen mensen aan 
aids.WR-P-P-E.lst  aids   WR-P-P-E      
aids.WR-P-P-G.lst  aids   WR-P-P-G      Veilige seks kan 

其他单词与单词不完全匹配(在这种情况下,它们后面都是-sometext,但破折号并不总是存在!aidsprobleem 等单词也应排除在外。第二行输出没有 leftContext,因为在数据中,它前面没有任何内容。

我希望我已经明确了我需要什么。我最感兴趣的是排除在句子中找不到单词的行(不区分大小写)。


我尝试在下面应用 tospig 的解决方案。 df 是我已经拥有的最后一个数据框,看起来像这样(只是一个视觉示例):

fileName         | node | component | precedingWord | leftContext                               | sentence 
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
aids.WR-P-P-D.lst  aids   WR-P-P-D    Het             Het                                         Het aids-probleem ontstaat door mensen zonder vaste partner, [...]
aids.WR-P-P-D.lst  aids   WR-P-P-D    aan             Vorig jaar stierven 3 miljoen mensen aan    Vorig jaar stierven 3 miljoen mensen aan aids en raakten er 5 miljoen besmet met hiv.
aids.WR-P-P-E.lst  aids   WR-P-P-E    meeste          Zuid-Afrika heeft de meeste                 Zuid-Afrika heeft de meeste aids-gevallen ter wereld.
aids.WR-P-P-E.lst  aids   WR-P-P-E                                                                Aids is geen pretje.
aids.WR-P-P-G.lst  aids   WR-P-P-G    kan             Veilige seks kan                            Veilige seks kan aids voorkomen.
aids.WR-P-P-G.lst  aids   WR-P-P-G    de              Want naarmate de                            Want naarmate de aids-epidemie in Zuid-Afrika en omliggende landen groeit [...]

然后我尝试删除在 sentence 中找不到 node 的行(在本例中为 1、3 和 6):

pattern <- c(" - .*","^- .*"," -$")
pattern <- gsub("-",df$node,pattern)
pattern <- paste0(pattern, collapse="|")

df1 <- df[grepl(pattern, df$sentence, ignore.case=TRUE),]

但是,gsub 给出了一个错误:

在 gsub("-", df$node, pattern) 中:参数 'replacement' 有长度 > 1 并且只使用第一个元素

这对我来说似乎是合乎逻辑的:我没有告诉 R 替换应该以每个单词为基础进行,例如应仅在具有 df$node = aids 的句子中查找艾滋病。

【问题讨论】:

  • 您可以使用正则表达式来获取包含您的单词的句子的索引:word &lt;- "adapter"; grep(paste0("\\b", word, "\\b"), gsub("[-]", "", c("Ik zie de adapters niet", "Waar is de adapter-aansluiting?", "Een aanpassing aan de adapter", ignore.case = TRUE)))
  • @lukeA 不使用\\b 也能抓住我试图避免的情况?比如aids-epidemie?见regex101.com/r/jE3nU4/1
  • 它会给你一个错误或警告吗? gsub("-",c("aids","aids"),"some - text"),与gsub("-","aids","some - text")
  • @tospig 第一个给出错误:参数'replacement'的长度> 1,并且只会使用第一个元素
  • 我的意思是“警告”与“错误”不同。我的示例试图证明您正在传递一个向量(长度 > 1)来替换长度为 1 的内容。“警告”告诉您操作“有效”,但只使用了向量的第一个元素

标签: r


【解决方案1】:

从另一个角度来看我(现已删除)之前的答案,

给出最终数据框e的示例

t1 <- "Het aids-probleem ontstaat door mensen zonder vaste partner, legt de speciale editie uit"
t2 <- "Vorig jaar stierven 3 miljoen mensen aan aids en raakten er 5 miljoen besmet met hiv"
t3 <- "Zuid-Afrika heeft de meeste aids-gevallen ter wereld."
t4 <- "Aids is geen pretje."
t5 <- "Veilige seks kan aids voorkomen."
t6 <- "Want naarmate de aids-epidemie in Zuid-Afrika en omliggende landen groeit"
node <- rep("aids",6)
t7 <- "Waar is de adapter-aansluiting?"
t8 <- "Een aanpassing aan de adapter"
node <- c(node, rep("adapter",2))  

e <- data.frame(node = node, sentence = c(t1, t2, t3, t4, t5, t6, t7, t8), stringsAsFactors=FALSE)

您可以对此进行子集化和使用正则表达式,而不是在读取文件时。

类似:

## vector of regex
e$pattern <- paste0(" ", e$node, " .*|^",e$node,".*| ", e$node, "$")

## create logical subset of rows matching the pattern
e$log <- apply(e, 1, function(x) {
  grepl(x["pattern"],x["sentence"],ignore.case=TRUE) 
})

## subset by 'TRUE'
e <- e[e$log,]

## create leftContext
e$leftContext <- apply(e, 1, function(x){
  sub(x["pattern"], "", x["sentence"], ignore.case=TRUE) 
})

这给了

> e[,c("node","sentence","leftContext")]
     node                                                                             sentence
2    aids Vorig jaar stierven 3 miljoen mensen aan aids en raakten er 5 miljoen besmet met hiv
4    aids                                                                 Aids is geen pretje.
5    aids                                                     Veilige seks kan aids voorkomen.
8 adapter                                                        Een aanpassing aan de adapter
                           leftContext
2 Vorig jaar stierven 3 miljoen mensen aan
4                                         
5                         Veilige seks kan
8                    Een aanpassing aan de

【讨论】:

  • 几件事。您分配给 e$leftContext 的行实际上应该是句子。 leftContext 包含单词中的所有 left 内容(例如 *Vorig jaar stierven 3 miljoen mensen aan *)。其次,我需要它动态工作,即所有单词(从文件名派生)。换句话说,我不能这样定义pattern。最后,当我测试这个时,我没有得到 [2] 作为输出。
  • 请在水平线下方查看我的编辑。我没有成功地使这种动态化。
  • 另外,这个正则表达式不是更简单吗? ( word |^word | word$)
  • @BramVanroy,我在正则表达式中添加了.*,以便稍后在sub 命令中使用
  • 正如您在我最初的帖子中看到的那样,我知道如何减去左侧上下文 (contexts &lt;- strsplit(df$sentence, df$node)) 但不起作用的是我真正需要的:删除没有的行句子中的节点。在使用 df$node 定义 pattern 时,我可能做错了。
猜你喜欢
  • 1970-01-01
  • 2023-03-14
  • 2014-09-26
  • 2016-06-21
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多