Selecionar todas as colunas que contêm uma string e retornar todas as suas linhas

Olá! Tenho uma dúvida que não estou conseguindo sanar por conta própria e gostaria de ajuda.

Tenho o seguinte dataframe com nomes de supermercados e produtos que eles vendem:

data <- 
  data.frame("super_mais" = c("arroz", "feijao", "carne", "frango", NA, NA),
             "super_bom" = c("macarrao", "cebola", NA, NA, NA, NA),
             "super_top" = c("arroz", "macarrao", "tomate", "frango", NA, NA),
             "super_show" = c("arroz", "feijao", "macarrao", "frango", "alface", "tomate"),
             "super_massa" = c("feijao", "carne", "alface", NA, NA, NA))

Eu gostaria de selecionar apenas as colunas correspondentes aos supermercados que vendem arroz. Para isso, tentei o seguinte:

data |> 
  pivot_longer(cols = starts_with("super"),
               names_to = "nome", values_to = "produto") |> 
  group_by(nome) |> 
  filter(any(str_detect(produto, "arroz"))) |> 
  ungroup() |> 
  pivot_wider(names_from = "nome", values_from = "produto")

Porém, tenho o seguinte resultado:

# A tibble: 1 × 3
  super_mais super_top super_show
  <list>     <list>    <list>    
1 <chr [6]>  <chr [6]> <chr [6]> 
Warning message:
Values from `produto` are not uniquely identified; output will contain list-cols.
• Use `values_fn = list` to suppress this warning.
• Use `values_fn = {summary_fun}` to summarise duplicates.
• Use the following dplyr code to identify duplicates.
  {data} %>%
  dplyr::group_by(nome) %>%
  dplyr::summarise(n = dplyr::n(), .groups = "drop") %>%
  dplyr::filter(n > 1L) 

Eu gostaria que ter uma resultado semelhante a este:

  super_mais super_top super_show
1      arroz     arroz      arroz
2     feijao  macarrao     feijao
3      carne    tomate   macarrao
4     frango    frango     frango
5       <NA>      <NA>     alface
6       <NA>      <NA>     tomate

Além disso, há alguma forma de obter este resultado de forma mais direta (sem usar o pivot_longer e depois o pivot_wider)? Meu dataframe original tem cerca de 10.000 colunas e acho que esses passos podem exigir um esforço computacional desnecessário, mas só consegui pensar em fazer assim.

Obrigado desde já!

Oi @nathanhonorato
Acho que esse script ja ajuda:

library(tidyverse)

data <- 
  data.frame("super_mais" = c("arroz", "feijao", "carne", "frango", NA, NA),
             "super_bom" = c("macarrao", "cebola", NA, NA, NA, NA),
             "super_top" = c("arroz", "macarrao", "tomate", "frango", NA, NA),
             "super_show" = c("arroz", "feijao", "macarrao", "frango", "alface", "tomate"),
             "super_massa" = c("feijao", "carne", "alface", NA, NA, NA))

colunas_filtrada <-  data %>%
  pivot_longer(everything(),  names_to = "supermecado", values_to = "produto") %>% 
  filter(produto == 'arroz')
  
data %>% select(colunas_filtrada$supermecado)

Abraços

1 curtida

Filter(function(x) any(x == "arroz"), data)

É “Filter” com F maiúsculo mesmo, é uma função de base R.
Não testei com um conjunto de dados maior, mas deve ser muito eficiente em termos de recursos.

Diz aí se era isso que você precisava! :slight_smile:

2 curtidas