【问题标题】:Subset dataframe if a $ symbol exists in a string column如果字符串列中存在 $ 符号,则子集数据框
【发布时间】:2017-08-18 17:48:30
【问题描述】:

我有一个 dataframe 与一个 time 列和一个 string 列。我想subset 这个dataframe - 我只保留string 列在其中某处包含$ 符号的行。

子集后,我想清理string 列,使其仅在$ 符号之后包含characters,直到出现spacesymbol

df <- data.frame("time"=c(1:10),
"string"=c("$ABCD test","test","test $EFG test",
"$500 test","$HI/ hello","test $JK/",
"testing/123","$MOO","$abc","123"))

我希望最终输出是:

Time  string  
1     ABCD
3     EFG
4     500
5     HI
6     JK
8     MOO
9     abc

它只保留字符串列中具有$ 的行,然后只保留$ 符号之后的字符,直到spacesymbol

我在sub 上取得了一些成功,只是为了提取string,但无法将其应用于df 并将其子集化。感谢您的帮助。

【问题讨论】:

    标签: r regex dataframe subset


    【解决方案1】:

    在有人提出漂亮的 解决方案之前,这是我的看法:

    # subset for $ signs and convert to character class
    res <- df[ grepl("$", df$string, fixed = TRUE),]
    res$string <- as.character(res$string)
    
    # split on non alpha and non $, and grab the one with $, then remove $
    res$clean <- sapply(strsplit(res$string, split = "[^a-zA-Z0-9$']", perl = TRUE),
                        function(i){
                          x <- i[grepl("$", i, fixed = TRUE)]
                          # in case when there is more than one $
                          # x <- i[grepl("$", i, fixed = TRUE)][1]
                          gsub("$", "", x, fixed = TRUE)
                        })
    res
    #   time         string clean
    # 1    1     $ABCD test  ABCD
    # 3    3 test $EFG test   EFG
    # 4    4      $500 test   500
    # 5    5     $HI/ hello    HI
    # 6    6      test $JK/    JK
    # 8    8           $MOO   MOO
    # 9    9           $abc   abc
    

    【讨论】:

    • 非常感谢。当我在我的数据集上运行它时遇到了一件我没有预见到的事情 - 一些字符串实际上多次出现 $string - 例如,一个值可能是 $ABCD test $EBC and $FB - 这导致值 @ 987654325@。是否可以只存储第一次出现?谢谢!
    • @newtoR 使用此行仅获取第一次出现的x &lt;- i[grepl("$", i, fixed = TRUE)][1],作为评论添加到帖子中
    【解决方案2】:

    我们可以通过提取regexpr/regmatches 的子字符串来仅提取$ 之后的子字符串

    i1 <- grep("$", df$string, fixed = TRUE)
    transform(df[i1,], string = regmatches(string, regexpr("(?<=[$])\\w+", string, perl = TRUE)))
    #    time string
    #1    1   ABCD
    #3    3    EFG
    #4    4    500
    #5    5     HI
    #6    6     JK
    #8    8    MOO
    #9    9    abc
    

    或者使用tidyverse 语法

    library(tidyverse)
    df %>% 
       filter(str_detect(string, fixed("$")))  %>%
       mutate(string = str_extract(string, "(?<=[$])\\w+"))
    

    【讨论】:

      猜你喜欢
      • 2017-09-09
      • 2021-01-22
      • 2021-06-25
      • 2020-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多