【问题标题】:How to filter and copy a value in R dataframe?如何过滤和复制 R 数据框中的值?
【发布时间】:2020-02-12 11:31:47
【问题描述】:

我有一个如下所示的数据框

Test <- c('Sodium','Heamo Index.','Lipae Index','ictoric index','Chloride','Blood pressure','Test Index')
value <- c(12,'No haemo',NA,'No ict',21,32,NA)
TextualResults <- c('low value',NA,'NO LIPA',NA,'HIGH','low','NO TEST')

df_test <- data.frame(Test,value,TextualResults)

输入如下图所示

我正在尝试这样的事情

library(tidyverse)

df_test %>%  
  filter(stringr::str_detect(type, 'index|Index|INDEX'))

但不确定如何根据NA检查复制值并以优雅的方式使搜索不区分大小写

我希望我的输出如下所示

如您所见,在Test 列下,每当我们找到包含index(不区分大小写)的值时,我们必须确保这些行的value 列不是NA

默认情况下,value 列下的 index 行可能具有值,但也可能是 NA

因此,当它是 NA 时,我们会选择 TextualResults 列下存在的任何值,并将其放回 value 列中以获取包含 index 术语的行。对于包含index 术语的行,基本上value 列永远不会是NA

【问题讨论】:

    标签: r dataframe tidyr dplyr


    【解决方案1】:

    可以试试:

    library(dplyr)
    
    df_test %>%
      mutate_all(as.character) %>% # or mutate_at(-1, as.character) if you'd like to keep first as factor
      mutate(
        value = case_when(
          grepl('index', Test, ignore.case = TRUE) ~ coalesce(value, TextualResults),
          TRUE ~ value
        )
      )
    

    输出:

                Test    value TextualResults
    1         Sodium       12      low value
    2    Heamo Index No haemo           <NA>
    3    Lipae Index  NO LIPA        NO LIPA
    4  ictoric index   No ict           <NA>
    5       Chloride       21           HIGH
    6 Blood pressure       32            low
    7     Test Index  NO TEST        NO TEST
    

    这应该适用于所有索引组合,无论它是在点、其他字符、大写/小写等之前还是之后。

    考虑一下:

    Test <- c('Sodium','Heamo Index.','Lipae Index..','ictoric __index','Chloride','Blood pressure','Test $$Index')
    value <- c(12,'No haemo',NA,NA,21,32,NA)
    TextualResults <- c('low value',NA,'NO LIPA','No ict','HIGH','low','NO TEST')
    
    df_test <- data.frame(Test,value,TextualResults)
    
                 Test    value TextualResults
    1          Sodium       12      low value
    2    Heamo Index. No haemo           <NA>
    3   Lipae Index..     <NA>        NO LIPA
    4 ictoric __index     <NA>         No ict
    5        Chloride       21           HIGH
    6  Blood pressure       32            low
    7    Test $$Index     <NA>        NO TEST
    

    使用上述代码输出:

                 Test    value TextualResults
    1          Sodium       12      low value
    2    Heamo Index. No haemo           <NA>
    3   Lipae Index..  NO LIPA        NO LIPA
    4 ictoric __index   No ict         No ict
    5        Chloride       21           HIGH
    6  Blood pressure       32            low
    7    Test $$Index  NO TEST        NO TEST
    

    【讨论】:

    • 感谢您的回复。赞成。 -1 是否表示列位置?它表示什么?
    • 这表明你在除第一列之外的所有列都发生了变异——所以确实,它表明了位置。
    • 好的,q1) 所以就像您将所有列转换为字符,然后应用 case_when 条件。 q2) 通过~ coalesce (value, TextualResults), do you copy data value from Textual 结果列到value 列? q3) TRUE ~value 做什么?
    • q1 ) 实际上,q2) coalesce 查看两列并取非缺失值,3) TRUE 等效于 else in ifelse,即它查看所有除了以任何形式包含 index 的行之外的行(并保持原样,即作为初始 value
    • 如果我不将所有内容都转换为字符,此解决方案是否有效?当我正在处理一百万条记录数据框时,只是想知道更改数据类型是否明智。
    【解决方案2】:

    我会使用if_else() 来实现这一点。为了避免因素,我首先将它变成一个小标题而不是数据框。

    Test <- c('Sodium','Heamo Index','Lipae Index','ictoric index','Chloride','Blood pressure','Test Index')
    value <- c(12,'No haemo',NA,'No ict',21,32,NA)
    TextualResults <- c('low value',NA,'NO LIPA',NA,'HIGH','low','NO TEST')
    df_test <- tibble(Test,value,TextualResults)
    
    contains_index <- str_detect(df_test$Test, 'index|Index|INDEX')
    
    new_df <-
      df_test %>%
      mutate(value = if_else(is.na(value) & contains_index, TextualResults, value))
    

    【讨论】:

    • 当然,我认为它的工作原理与数据框几乎相同:tibble.tidyverse.org。只要列是字符而不是因子,我的代码也可以使用数据框。
    【解决方案3】:
    library(dplyr)
    # Change value and TextualResults from factor to character
    df_test[-1] <- lapply(df_test[-1], as.character)
    
    
    df_test <- 
      df_test %>% 
      mutate(value = if_else(grepl("Index", Test, ignore.case = TRUE) & is.na(value), TextualResults, value))
    
    df_test
                Test    value TextualResults
    1         Sodium       12      low value
    2    Heamo Index No haemo           <NA>
    3    Lipae Index  NO LIPA        NO LIPA
    4  ictoric index   No ict           <NA>
    5       Chloride       21           HIGH
    6 Blood pressure       32            low
    7     Test Index  NO TEST        NO TEST
    

    【讨论】:

    • 感谢您的回复。赞成。 -1 表示什么?
    • 这是否也认为它是“索引”。带点的意思...我的术语可以像“溶血指数”。或像“黄疸指数”
    • “。”呢?在索引的末尾?
    【解决方案4】:
    df_test %>%
       mutate(value = ifelse(is.na(value) & Test %like% 'index|Index|INDEX', as.character(TextualResults), as.character(value)))
                Test    value TextualResults
    1         Sodium       12      low value
    2   Heamo Index. No haemo           <NA>
    3    Lipae Index  NO LIPA        NO LIPA
    4  ictoric index   No ict           <NA>
    5       Chloride       21           HIGH
    6 Blood pressure       32            low
    7     Test Index  NO TEST        NO TEST
    

    让我们稍微修改一下:

    Test <- c('Sodium','Heamo ..Index..','Lipae .Index_','ictoric ?index  ','Chloride','Blood pressure','Test Index')
    value <- c(12,'No haemo',NA,'No ict',21,32,NA)
    TextualResults <- c('low value',NA,'NO LIPA',NA,'HIGH','low','NO TEST')
    df_test <- data.frame(Test,value,TextualResults)
    
    df_test
                  Test    value TextualResults
    1           Sodium       12      low value
    2  Heamo ..Index.. No haemo           <NA>
    3    Lipae .Index_     <NA>        NO LIPA
    4 ictoric ?index     No ict           <NA>
    5         Chloride       21           HIGH
    6   Blood pressure       32            low
    7       Test Index     <NA>        NO TEST
    

    结果是一样的:

                  Test    value TextualResults
    1           Sodium       12      low value
    2  Heamo ..Index.. No haemo           <NA>
    3    Lipae .Index_  NO LIPA        NO LIPA
    4 ictoric ?index     No ict           <NA>
    5         Chloride       21           HIGH
    6   Blood pressure       32            low
    7       Test Index  NO TEST        NO TEST
    

    【讨论】:

    • 您好 Adamm,感谢您的回复。赞成。它是否也考虑“索引”。或“索引”或“索引”。这意味着它可以包含空格或点,如我的示例中所示
    • 我认为%like% 将考虑所有索引类型,无论是点还是空格,例如其他答案中提到的grep。除非你有类似 `in.dex' 的东西,否则它可能是个问题。
    • 我在索引周围添加了一些额外的字符。
    • %like%grep 的包装器,而不是完全不同的函数。它的工作原理是一样的,只是你不能忽略这种情况。不知道为什么 OP 会看到根本没有的问题。
    猜你喜欢
    • 2018-01-07
    • 2020-04-17
    • 2021-11-22
    • 2014-10-03
    • 1970-01-01
    • 2017-08-15
    • 2017-12-30
    • 2021-12-08
    • 1970-01-01
    相关资源
    最近更新 更多