web-dev-qa-db-fra.com

convertir plusieurs colonnes de caractères en format numérique en r

Quel est le moyen le plus efficace de convertir plusieurs colonnes dans un cadre de données du format de caractères au format numérique?

J'ai un dataframe appelé DF avec toutes les variables de caractère.

Je voudrais faire quelque chose comme

for (i in names(DF){
    DF$i <- as.numeric(DF$i)
}

Je vous remercie

9
ec0n0micus

Tu pourrais essayer

DF <- data.frame("a" = as.character(0:5),
                 "b" = paste(0:5, ".1", sep = ""),
                 "c" = letters[1:6],
                 stringsAsFactors = FALSE)

# Check columns classes
sapply(DF, class)

#           a           b           c 
# "character" "character" "character" 

cols.num <- c("a","b")
DF[cols.num] <- sapply(DF[cols.num],as.numeric)
sapply(DF, class)

#          a           b           c 
#  "numeric"   "numeric" "character"
33
Luca Braglia

Vous pouvez utiliser l'index des colonnes: data_set[,1:9] <- sapply(dataset[,1:9],as.character)

4
Masimi

Si vous utilisez déjà le Tidyverse, il existe plusieurs solutions en fonction de la situation:

library(dplyr)
library(magrittr)

# solution
dataset %<>% mutate_if(is.character,as.numeric)

# to test
df <- data.frame(
  x1 = c('1','2','3'),
  x2 = c('4','5','6'),
  x3 = c('1','a','b'), # vector with alpha characters
  stringsAsFactors = F)

# display starting structure
df %>% str()

Convertir tous les vecteurs de caractères en numériques (ils pourraient échouer s'ils n'étaient pas numériques)

df %>%
  select(-x3) %>% # this removes the alpha column if all your character columns need converted to numeric
  mutate_if(is.character,as.numeric) %>%
  str()

Vérifiez si chaque colonne peut être convertie. Cela peut être une fonction anonyme. Il vérifie si as.numeric renvoie NA. Il vérifie également si c'est un vecteur de caractère pour ignorer les facteurs. Cela supprime également les avertissements puisque vous savez que les AN seront introduites volontairement et vérifiées ultérieurement.

numericcharacters <- function(x) {
  !any(is.na(suppressWarnings(as.numeric(x)))) & is.character(x)
}
df %>% 
  mutate_if(numericcharacters,as.numeric) %>%
  str()

Si vous voulez convertir des colonnes nommées spécifiques, alors mutate_at est préférable.

df %>% mutate_at('x1',as.numeric) %>% str()
4
ARobertson

Je pense que je l'ai compris. Voici ce que j’ai fait (la solution n’est peut-être pas la plus élégante - des suggestions sur la manière de l’améliorer sont les bienvenues)

#names of columns in data frame
cols <- names(DF)
# character variables
cols.char <- c("fx_code","date")
#numeric variables
cols.num <- cols[!cols %in% cols.char]

DF.char <- DF[cols.char]
DF.num <- as.data.frame(lapply(DF[cols.num],as.numeric))
DF2 <- cbind(DF.char, DF.num)
2
ec0n0micus

Je me rends compte que c’est un vieux sujet mais je voulais poster une solution similaire à votre demande de fonction (je viens de rencontrer le problème similaire moi-même en essayant de formater un tableau entier en libellés de pourcentage).

Supposons que vous ayez un df avec 5 colonnes de caractères à convertir. Tout d'abord, je crée un tableau contenant les noms des colonnes que je veux manipuler:

col_to_convert <- data.frame(nrow = 1:5
                            ,col = c("col1","col2","col3","col4","col5"))

for (i in 1:max(cal_to_convert$row))
  {
    colname <- col_to_convert$col[i]
    colnum <- which(colnames(df) == colname)
        for (j in 1:nrow(df))
          {
           df[j,colnum] <- as.numericdf(df[j,colnum])
          }
  }

Ce n'est pas idéal pour les grandes tables, car cela va cellule par cellule, mais cela ferait le travail.

2
Mark Wagner

Vous pouvez utiliser convert à partir du paquet hablar:

library(dplyr)
library(hablar)

# Sample df (stolen from the solution by Luca Braglia)
df <- tibble("a" = as.character(0:5),
                 "b" = paste(0:5, ".1", sep = ""),
                 "c" = letters[1:6])

# insert variable names in num()
df %>% convert(num(a, b))

Ce qui vous donne:

# A tibble: 6 x 3
      a     b c    
  <dbl> <dbl> <chr>
1    0. 0.100 a    
2    1. 1.10  b    
3    2. 2.10  c    
4    3. 3.10  d    
5    4. 4.10  e    
6    5. 5.10  f   

Si vous êtes paresseux, laissez retype () de hablar deviner le type de données souhaité:

df %>% retype()

ce qui vous donne:

# A tibble: 6 x 3
      a     b c    
  <int> <dbl> <chr>
1     0 0.100 a    
2     1 1.10  b    
3     2 2.10  c    
4     3 3.10  d    
5     4 4.10  e    
6     5 5.10  f   
1
davsjob

comme ça?

DF <- data.frame("a" = as.character(0:5),
             "b" = paste(0:5, ".1", sep = ""),
             "c" = paste(10:15),
             stringsAsFactors = FALSE)

DF <- apply(DF, 2, as.numeric)

S'il y a des "vrais" caractères dans le cadre de données comme "a" "b" "c", je recommanderais de répondre depuis davsjob.

0
tickly potato