【问题标题】:Select rows from data.frame ending with a specific character string in R从data.frame中选择以R中特定字符串结尾的行
【发布时间】:2012-10-12 07:30:10
【问题描述】:

我正在使用 R,并且我有一个包含近 2,000 个条目的 data.frame,如下所示:

> head(PVs,15)
     LogFreq   Word PhonCV  FreqDev
1593     140    was    CVC 5.480774
482      139    had    CVC 5.438114
1681     138    zou   CVVC 5.395454
1662     137    zei    CVV 5.352794
1619     136   werd   CVCC 5.310134
1592     135  waren CVV-CV 5.267474
620      134    kon    CVC 5.224814
646      133   kwam   CCVC 5.182154
483      132 hadden CVC-CV 5.139494
436      131   ging    CVC 5.096834
734      130  moest  CVVCC 5.054174
1171     129  stond  CCVCC 5.011514
1654     128    zag    CVC 4.968854
1620     127 werden CVC-CV 4.926194
1683     126 zouden CVV-CV 4.883534

我想要做的是创建一个等于 PVs 的新 data.frame,除了所有条目都具有作为“Word”列的成员的字符串不以“te”或“de”被删除。即所有不以“de”或“te”结尾的单词都应该从data.frame中删除。

我知道如何使用逻辑运算符从 data.frames 中选择性地删除条目,但是当您设置数字标准时,它们会起作用。我认为要做到这一点,我需要使用正则表达式,但遗憾的是 R 是我“知道”的唯一编程语言,所以我远不知道在这里使用什么类型的代码。

感谢您的帮助。 提前致谢。

【问题讨论】:

    标签: regex string r character dataframe


    【解决方案1】:

    方法一

    您可以将grepl 与适当的正则表达式一起使用。考虑以下几点:

    x <- c("blank","wade","waste","rubbish","dedekind","bated")
    grepl("^.+(de|te)$",x)
    [1] FALSE  TRUE  TRUE FALSE FALSE FALSE
    

    正则表达式以任意次数 (.+) 开始 (^),然后找到 de 或 te ((de|te)) 然后结束 ($)。

    所以对于你的 data.frame 试试,

    subset(PVs,grepl("^.+(de|te)$",Word))
    

    方法二

    要避免使用 regexp 方法,您可以改用 substr 方法。

    # substr the last two characters and test
    substr(x,nchar(x)-1,nchar(x)) %in% c("de","te")
    [1] FALSE  TRUE  TRUE FALSE FALSE FALSE
    

    那就试试吧:

    subset(PVs,substr(Word,nchar(Word)-1,nchar(Word)) %in% c("de","te"))
    

    【讨论】:

    • 谢谢@James 我试过了,但我似乎没有得到我想要的结果。我按照对我的数据的建议应用了您的命令,但留下的单词绝不是仅以“de”和“te”结尾的单词。确实有近 100 个条目被删除,但我不知道是哪个条目,或者根据什么标准。然后,我尝试创建一个新列,如果条目适应正则表达式,则为 FALSE,但结果看起来不太好,例如,单词“aandrong”为 TRUE,但显然没有以我想要的结局。知道可能出了什么问题吗?
    • @Hernan_L 我已经为答案添加了另一种方法。
    • @Hernan_L 现在我已经修复了正则表达式,所以它也应该可以工作。
    • 非常感谢詹姆斯。我使用了您的新正则表达式,现在它可以完美运行。额外的 $ 符号在做什么?无论如何,子集函数也有效,但我坚持使用正则表达式,因为我将使用它来选择更多类型的单词。再次,非常感谢。
    • @Hernan_L $ 符号匹配行尾的空字符串。它确保比赛在工作结束时进行。使用我提供的示例向量尝试不使用它。
    【解决方案2】:

    我对数据进行了一些修改,以使单词以 te 或 de 结尾。

    > PV
         LogFreq   Word PhonCV  FreqDev
    1593     140 blahte    CVC 5.480774
    482      139    had    CVC 5.438114
    1681     138 aaaade   CVVC 5.395454
    1662     137    zei    CVV 5.352794
    1619     136   werd   CVCC 5.310134
    1592     135  waren CVV-CV 5.267474
    620      134    kon    CVC 5.224814
    646      133 kwamde   CCVC 5.182154
    483      132 hadden CVC-CV 5.139494
    436      131   ging    CVC 5.096834
    734      130 moeste  CVVCC 5.054174
    1171     129  stond  CCVCC 5.011514
    1654     128  zagde    CVC 4.968854
    1620     127 werden CVC-CV 4.926194
    1683     126 zouden CVV-CV 4.883534
    
    # Add a column to PV that you can visually check the regular expression matches.
    PV$Match <- grepl(pattern = "(de|te)$", PV$Word)
    
    # Subset PV data frame to show only TRUE matches
    PV <- PV[PV$Match == FALSE, ]
    

    结果如下图

         LogFreq   Word PhonCV  FreqDev Match
    482      139    had    CVC 5.438114 FALSE
    1662     137    zei    CVV 5.352794 FALSE
    1619     136   werd   CVCC 5.310134 FALSE
    1592     135  waren CVV-CV 5.267474 FALSE
    620      134    kon    CVC 5.224814 FALSE
    483      132 hadden CVC-CV 5.139494 FALSE
    436      131   ging    CVC 5.096834 FALSE
    1171     129  stond  CCVCC 5.011514 FALSE
    1620     127 werden CVC-CV 4.926194 FALSE
    1683     126 zouden CVV-CV 4.883534 FALSE
    

    【讨论】:

    • 感谢@RossB,添加带有逻辑值的附加列的想法是个好主意,因为它让我可以看到函数对原始数据的影响。此外,正则表达式工作正常。谢谢!
    【解决方案3】:

    使用 grep

    grep -xvE '.{17}(de|te).*' file.txt
    

    【讨论】:

    • 感谢@Ωmega 为您解答。您能否更具体地说明此命令的作用以及如何将其应用于我的数据?
    最近更新 更多