Как отфильтровать и скопировать значение в R данных? - PullRequest
1 голос
/ 12 февраля 2020

У меня есть кадр данных, как показано ниже

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)

Вход выглядит так, как показано ниже

enter image description here

Я пытался что-то вроде этого

library(tidyverse)

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

Но не уверен, как скопировать значение на основе проверки NA и сделать поиск нечувствительным к регистру элегантным способом

Я ожидаю, что мой вывод будет таким, как показано ниже

enter image description here

Как вы можете видеть в столбце Test, всякий раз, когда мы найти значения, которые содержат index (без учета регистра), мы должны убедиться, что столбец value не является NA для этих строк.

Данные по умолчанию могут иметь значение для index строк в столбце value, но также могут быть NA.

Итак, когда это NA, мы выбираем любое значение присутствует в столбце TextualResults и помещается обратно в столбец value для строк, содержащих термин index. В основном столбец value никогда не будет NA для строк, содержащих index term

Ответы [ 4 ]

3 голосов
/ 12 февраля 2020

Можно попробовать:

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

Это должно работать для всех комбинаций индекса, независимо от того, предшествует ли ему точка или после нее, другие символы, верхний / строчные буквы, et c.

Учитывайте это:

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 голос
/ 12 февраля 2020
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
1 голос
/ 12 февраля 2020

Я бы использовал if_else() для достижения sh этого. Сначала я делаю это в виде таблицы, а не фрейма данных, чтобы избежать факторов.

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))
1 голос
/ 12 февраля 2020
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
...