AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79166532
Accepted
Wael
Wael
Asked: 2024-11-07 20:52:28 +0800 CST2024-11-07 20:52:28 +0800 CST 2024-11-07 20:52:28 +0800 CST

Tendo problemas com which.min dentro do pipe dplyr

  • 772

Tenho alguns problemas com which.mina função dentro de um pipe dplyr. Tenho um problema solution (*)e estou procurando uma maneira mais compacta e elegante de fazer isso.

  1. exemplo reproduzível
library(dplyr)

data=data.frame(s1=c(10,NA,5,NA,NA),s2=c(8,NA,NA,4,20),s3=c(NA,NA,2,NA,10))
data
#>   s1 s2 s3
#> 1 10  8 NA
#> 2 NA NA NA
#> 3  5 NA  2
#> 4 NA  4 NA
#> 5 NA 20 10
  1. Valor mínimo:

aqui com min(x,na.rm=TRUE)eu poderia extrair o valor mínimo

data%>%
  rowwise()%>%
  mutate(Min_s=min(c(s1,s2,s3),na.rm=TRUE))
#> Warning: There was 1 warning in `mutate()`.
#> ℹ In argument: `Min_s = min(c(s1, s2, s3), na.rm = TRUE)`.
#> ℹ In row 2.
#> Caused by warning in `min()`:
#> ! no non-missing arguments to min; returning Inf
#> # A tibble: 5 × 4
#> # Rowwise: 
#>      s1    s2    s3 Min_s
#>   <dbl> <dbl> <dbl> <dbl>
#> 1    10     8    NA     8
#> 2    NA    NA    NA   Inf
#> 3     5    NA     2     2
#> 4    NA     4    NA     4
#> 5    NA    20    10    10
  1. extraindo variável contendo min val:

Aqui estou tendo problemas para extrair qual variável contém o valor mínimo

data%>%
  rowwise()%>%
  mutate(which_s=which.min(c(s1,s2,s3)))
#> Error in `mutate()`:
#> ℹ In argument: `which_s = which.min(c(s1, s2, s3))`.
#> ℹ In row 2.
#> Caused by error:
#> ! `which_s` must be size 1, not 0.
#> ℹ Did you mean: `which_s = list(which.min(c(s1, s2, s3)))` ?

# Solution (*)
data%>%
  rowwise()%>%
  mutate(which_s=if(!is.na(s1)|!is.na(s2)|!is.na(s3)) {which.min(c(s1,s2,s3))} else NA )
#> # A tibble: 5 × 4
#> # Rowwise: 
#>      s1    s2    s3 which_s
#>   <dbl> <dbl> <dbl>   <int>
#> 1    10     8    NA       2
#> 2    NA    NA    NA      NA
#> 3     5    NA     2       3
#> 4    NA     4    NA       2
#> 5    NA    20    10       3

Criado em 2024-11-07 com reprex v2.1.0

  • 3 3 respostas
  • 76 Views

3 respostas

  • Voted
  1. Best Answer
    ThomasIsCoding
    2024-11-07T21:23:12+08:002024-11-07T21:23:12+08:00

    Na segunda linha, você obterá integer(0)na coluna which_s, e é nesse ponto que você não poderá executá-lo sem erros.

    Em vez disso, você pode primeiro armazenar os resultados em uma lista e então unnest(não se esqueça de habilitar keep_emptyo argumento em unnest)

    data %>%
        rowwise() %>%
        mutate(which_s = list(which.min(c(s1, s2, s3)))) %>%
        unnest(which_s, keep_empty = TRUE)
    

    o que dá

    # A tibble: 5 × 4
         s1    s2    s3 which_s
      <dbl> <dbl> <dbl>   <int>
    1    10     8    NA       2
    2    NA    NA    NA      NA
    3     5    NA     2       3
    4    NA     4    NA       2
    5    NA    20    10       3
    
    • 7
  2. jpsmith
    2024-11-07T21:27:01+08:002024-11-07T21:27:01+08:00

    Sem usar rowwise(), você pode fazer isso no R básico ou em uma única mutate()etapa usando purrr::pmap_chr():

    Base R:

    data$min_base <- unlist(apply(data, 1, \(x) ifelse(all(is.na(x)), NA, names(data)[which.min(x)])))
    

    dplyr/purrr

    library(dplyr)
    
    data <- data %>%
      mutate(min_dplyr = purrr::pmap_chr(select(., s1:s3), \(...) {
        ifelse(all(is.na(c(...))), NA, colnames(data)[which.min(c(...))])
      }))
    

    Saída:

    #   s1 s2 s3 min_base min_dplyr
    # 1 10  8 NA       s2        s2
    # 2 NA NA NA     <NA>      <NA>
    # 3  5 NA  2       s3        s3
    # 4 NA  4 NA       s2        s2
    # 5 NA 20 10       s3        s3
    

    Observe que, entre essas respostas, a função personalizada R básica de @friede é substancialmente mais rápida, seguida por esta abordagem R básica:

    bigdata <- data[rep(seq_len(nrow(data)), 1e5),]
    
    microbenchmark::microbenchmark(
      rowwise = bigdata %>%
        rowwise() %>%
        mutate(which_s = list(which.min(c(s1, s2, s3)))) %>%
        tidyr::unnest(which_s, keep_empty = TRUE),
      base = unlist(apply(bigdata, 1, \(x) ifelse(all(is.na(x)), NA, names(bigdata)[which.min(x)]))),
      pmap = bigdata %>%
        mutate(min_dplyr = purrr::pmap_chr(select(., s1:s3), \(...) {
          ifelse(all(is.na(c(...))), NA, colnames(bigdata)[which.min(c(...))])
        })),
      custom_row.which.min = row.which.min(bigdata, names = TRUE, ties="first")
    )
    
    #                 expr       min       lq      mean    median        uq       max neval cld
    #              rowwise 3730.8131 4512.870 6018.3180 4985.6024 5913.5166 53501.838   100 a  
    #                 base 2419.1913 3162.745 4309.7700 3557.7805 4427.4588 32814.209   100  b 
    #                 pmap 3837.8870 4593.846 6091.5265 5203.0391 5984.0412 22015.418   100 a  
    # custom_row.which.min  108.4075  147.695  221.7602  168.5267  240.6043  1419.106   100   c
    
    • 2
  3. 2024-11-07T23:32:47+08:002024-11-07T23:32:47+08:00

    Às vezes, sinto falta de uma boa row.which.minfunção. Isso está longe de ser bom e não está harmonizado para funcionar (bem) com {dplyr}-language, mas pode ajudar aqui.

    v0

    row.which.min = \(.data, .cols, .names = FALSE, tm = "first") {
      if(missing(.cols)) .cols = names(.data)
      x = .data[.cols]
      i = rowSums(is.na(x)) < length(.cols)
      nx = -x[i, ]
      nx[is.na(nx)] = -Inf
      y = rep(NA, nrow(.data))
      y[i] = max.col(nx, tm)
      if(!.names) y else names(.data)[y]
    }
    

    dando

    > df0 = data.frame(s1=c(10,NA,5,NA,NA),s2=c(8,NA,NA,4,20),s3=c(NA,NA,2,NA,10))
    > row.which.min(df0, .names = TRUE)
    [1] "s2" NA   "s3" "s2" "s3"
    
    • 2

relate perguntas

  • Adicionar número de série para atividade de cópia ao blob

  • A fonte dinâmica do empacotador duplica artefatos

  • Selecione linhas por grupo com 1s consecutivos

  • Lista de chamada de API de gráfico subscritoSkus estados Privilégios insuficientes enquanto os privilégios são concedidos

  • Função para criar DFs separados com base no valor da coluna

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve