web-dev-qa-db-fra.com

pivot_longer avec plusieurs classes provoque une erreur ("Pas de type commun")

Je cours pivot_longer sur plusieurs colonnes (c'est-à-dire deux colonnes de caractères et une numérique). Je rencontre une erreur liée au décalage de classe.

J'ai étudié la documentation des options "forcer" et je n'ai vu aucun argument dans pivot_longer pour spécifier la classe à utiliser - ou pour permettre à la fonction de détecter automatiquement la classe la plus générale.

Y a-t-il des paramètres dans pivot_longer pour éviter cette erreur? Ou devez-vous convertir les colonnes en une seule classe avant d'exécuter pivot_longer?

library(dplyr)
library(tidyr)
library(ggplot2) # Just for `diamonds` dataset

small_diamonds <- diamonds %>% 
  # Select a few columns (two character, one numeric, specifically integers)
  select(cut, color, price) %>% 
  # Create a row_id
  mutate(row_num = row_number()) 

# This works with `gather`
small_diamonds %>% 
  gather(key, val, - row_num)

# This fails due to class error:
small_diamonds %>% 
  # Pivot data
  pivot_longer( - row_num, 
                names_to = "key",
                values_to = "val")

# Output
# Error: No common type for `cut` <ordered<4bd7e>> and `price` <integer>.
# Call `rlang::last_error()` to see a backtrace

# Convert columns to a single class (character) and then use `pivot_longer`. 
# Runs successfully
small_diamonds %>% 
  mutate_all(as.character) %>% 
  # Pivot data
  pivot_longer( - row_num, 
                names_to = "key",
                values_to = "val")

6
Ryan Baxter-King

En utilisant votre exemple, vous pouvez voir avec str () que vous avez deux vecteurs encodés en facteurs et deux en entiers. pivot_longer exige que tous les vecteurs soient du même type et renvoie l'erreur que vous avez signalée.

    library(tidyverse)
    small_diamonds <- diamonds %>%
      select(cut, color, price) %>%
      mutate(row_num = row_number())

    str(small_diamonds)

Une solution consiste à convertir tous les vecteurs en caractères avec mutate.if, puis à passer la commande pivot_longer.

    small_diamonds %>% 
      mutate_if(is.numeric,as.character, is.factor, as.character) %>% 
      pivot_longer( - row_num, 
            names_to = "key",
            values_to = "val") 
0
BMLopes