Próbuję posprzątać przykładowy arkusz informacji, który pochodzi z wielu różnych grup, a zatem informacje oczyszczania, na których dbam, może znajdować się w dowolnej liczbie różnych kolumn. Oto abstrakcyjny przykład:

sample_info = tribble(
  ~id, ~could_be_here, ~or_here,    ~or_even_in_this_one,
  1,   NA,             "not_me",    "find_me_other_stuff",
  2,   "Extra_Find_Me", NA,         "diff_stuff",
  3,   NA,              "Find_me",  NA,
  4,   NA,              "not_here", "not_here_either"
)

Gdzie chciałbym znaleźć "Find_me" 1) Case-Insurely, 2) gdzie może być w dowolnej kolumnie i 3), gdzie może być w ramach większego ciągu. Chcę utworzyć jedną kolumnę, która jest prawdziwa lub fałszywa, czy "Find_me" znaleziono w dowolnych kolumnach. Jak mogę to zrobić? (Pomyślałem o unite ing wszystkich kolumn, a następnie uruchomić str_detect na tym bałaganie, ale musi być mniej hacky, prawda?)

Aby być jasnym, chciałbym, aby ostateczne kociołki, które jest odpowiednikiem sample_info %>% mutate(find_me = c(TRUE, TRUE, TRUE, FALSE)).

Spodziewam się, że chciałbym użyć czegoś takiego jak stringr::str_detect(., regex('find_me', ignore_case = T)) i pmap_lgl(any(c(...) <insert logic check>)) i pmap_lgl(any(c(...) <insert logic check>)) jak w podobnych przypadkach połączone poniżej, ale nie jestem pewien, jak umieścić je w oświadczeniu o zmutowanej zgodności.

Rzeczy, przez które przeglądałem:
Operacja Wise Wise Jeśli jakieś kolumny znajdują się w jakiejkolwiek innej liście

R: Jak ignorować obudowę podczas korzystania z str_detect?

W R, sprawdź, czy ciąg pojawia się w wierszu Dataframe (w dowolnej kolumnie)

4
GenesRus 23 marzec 2021, 01:38

4 odpowiedzi

Najlepsza odpowiedź

Jedną z opcji dplyr i purrr może być:

sample_info %>%
 mutate(find_me = pmap_lgl(across(-id), ~ any(str_detect(c(...), regex("find_me", ignore_case = TRUE)), na.rm = TRUE)))

     id could_be_here or_here  or_even_in_this_one find_me
  <dbl> <chr>         <chr>    <chr>               <lgl>  
1     1 <NA>          not_me   find_me_other_stuff TRUE   
2     2 Extra_Find_Me <NA>     diff_stuff          TRUE   
3     3 <NA>          Find_me  <NA>                TRUE   
4     4 <NA>          not_here not_here_either     FALSE

Lub przy użyciu dplyr:

sample_info %>%
 rowwise() %>%
 mutate(find_me = any(str_detect(c_across(-id), regex("find_me", ignore_case = TRUE)), na.rm = TRUE))
4
tmfmnk 22 marzec 2021, 22:49

Mam nadzieję, że mam to, co masz na myśli. W ten sposób znajduję wszystko find_me s na wielu kolumnach:

library(dplyr)
library(purrr)
library(stringr)

sample_info = tribble(
  ~id, ~could_be_here, ~or_here,    ~or_even_in_this_one,
  1,   NA,             "not_me",    "find_me_other_stuff",
  2,   "Extra_Find_Me", NA,         "diff_stuff",
  3,   NA,              "Find_me",  NA,
  4,   NA,              "not_here", "not_here_either"
)

sample_info %>%
  mutate(find_me_exist = if_any(, ~ str_detect(., regex("find_me", ignore_case = TRUE), )
                                , .names = "{.col}.fn{.fn}"))

# A tibble: 4 x 5
     id could_be_here or_here  or_even_in_this_one find_me_exist
  <dbl> <chr>         <chr>    <chr>               <lgl>        
1     1 NA            not_me   find_me             TRUE         
2     2 Extra_Find_me NA       diff_stuff          TRUE         
3     3 NA            find_Me  NA                  TRUE         
4     4 NA            not_here not_here_either     FALSE

Przepraszam, musiałem edytować mój kod, aby nie był wrażliwy na wielkość liter.

3
Anoushiravan R 22 marzec 2021, 23:05

Chociaż powiedziano mi, że używasz zastosowania () w takich przypadkach jest niebezpieczne (nie jest pewnie dlaczego), to dla mnie zadziałało:

sample_info$find_me<-apply(sapply(sample_info, function(x) grepl('find_me', x, ignore.case = TRUE)), 1, any)

Ale mam wrażenie, że za każdym razem, gdy używam zagnieżdżonych funkcji aplikacji / Sapply / Lapply, musi być lepszy sposób ...

2
GuedesBF 23 marzec 2021, 01:48

W przypadku, gdy chcesz spróbować Hacky Way, twój pomysł na używanie unite w rzeczywistości działa:

 sample_info %>% unite(new, remove = FALSE) %>% 
    mutate(found = str_detect(.$new, regex("find_me", ignore_case = TRUE))) %>% 
    select(-new)
1
awaji98 23 marzec 2021, 09:51