web-dev-qa-db-fra.com

Comment puis-je remplacer les valeurs TRUE et FALSE par 1 et 0 lors de l'exportation de données dans R?

J'exporte des données de R avec la commande:

write.table(output,file="data.raw", na "-9999",sep="\t",row.names=F,col.names=F)

qui exporte mes données correctement, mais il exporte toutes les variables logiques en tant que VRAI et FAUX.

J'ai besoin de lire les données dans un autre programme qui ne peut traiter que des valeurs numériques. Existe-t-il un moyen efficace de les convertir en 1 et 0 numériques lors de l'exportation? J'ai un grand nombre de variables numériques, donc j'espérais parcourir automatiquement toutes les variables dans le data.table

Je me rends compte que je pourrais exécuter un script sed simple sur les données de sortie, mais il semble que cela devrait être simple à faire à partir de R.

Alternativement, mon objet de sortie est un data.table. Existe-t-il un moyen efficace de convertir toutes les variables logiques d'un data.table en variables numériques?

Dans le cas où cela est utile, voici du code pour générer un data.table avec une variable logique (ce n'est pas un grand nombre de variables logiques, mais assez pour utiliser sur un exemple de code):

DT = data.table(cbind(1:100,rnorm(100)>0)
DT[ ,V3:= V2==1 ]
DT[ ,V4:= V2!=1 ]

Cela semble être une question facile, mais ça me déstabilise, alors merci pour l'aide!

20
johneric

Pour un data.frame, vous pouvez convertir toutes les colonnes logiques en numérique avec:

# The data
set.seed(144)
dat <- data.frame(V1=1:100,V2=rnorm(100)>0)
dat$V3 <- dat$V2 == 1
head(dat)
#   V1    V2    V3
# 1  1 FALSE FALSE
# 2  2  TRUE  TRUE
# 3  3 FALSE FALSE
# 4  4 FALSE FALSE
# 5  5 FALSE FALSE
# 6  6  TRUE  TRUE

# Convert all to numeric
cols <- sapply(dat, is.logical)
dat[,cols] <- lapply(dat[,cols], as.numeric)
head(dat)
#   V1 V2 V3
# 1  1  0  0
# 2  2  1  1
# 3  3  0  0
# 4  4  0  0
# 5  5  0  0
# 6  6  1  1

Dans data.table syntaxe:

# Data
set.seed(144)
DT = data.table(cbind(1:100,rnorm(100)>0))
DT[,V3 := V2 == 1]
DT[,V4 := FALSE]
head(DT)
#    V1 V2    V3    V4
# 1:  1  0 FALSE FALSE
# 2:  2  1  TRUE FALSE
# 3:  3  0 FALSE FALSE
# 4:  4  0 FALSE FALSE
# 5:  5  0 FALSE FALSE
# 6:  6  1  TRUE FALSE

# Converting
(to.replace <- names(which(sapply(DT, is.logical))))
# [1] "V3" "V4"
for (var in to.replace) DT[, (var):= as.numeric(get(var))]
head(DT)
#    V1 V2 V3 V4
# 1:  1  0  0  0
# 2:  2  1  1  0
# 3:  3  0  0  0
# 4:  4  0  0  0
# 5:  5  0  0  0
# 6:  6  1  1  0
24
josliber

Qu'en est-il juste d'un:

dat <- data.frame(le = letters[1:10], lo = rep(c(TRUE, FALSE), 5))
dat
   le    lo
1   a  TRUE
2   b FALSE
3   c  TRUE
4   d FALSE
5   e  TRUE
6   f FALSE
7   g  TRUE
8   h FALSE
9   i  TRUE
10  j FALSE
dat$lo <- as.numeric(dat$lo)
dat
   le lo
1   a  1
2   b  0
3   c  1
4   d  0
5   e  1
6   f  0
7   g  1
8   h  0
9   i  1
10  j  0

ou une autre approche pourrait être avec dplyr afin de conserver la colonne précédente si le cas (personne ne le sait) vos données seront importées dans R.

library(dplyr)
dat <- dat %>% mutate(lon = as.numeric(lo))
dat
Source: local data frame [10 x 3]

   le    lo lon
1   a  TRUE   1
2   b FALSE   0
3   c  TRUE   1
4   d FALSE   0
5   e  TRUE   1
6   f FALSE   0
7   g  TRUE   1
8   h FALSE   0
9   i  TRUE   1
10  j FALSE   0

Modifier: boucle

Je ne sais pas si mon code fonctionne ici, mais il vérifie toutes les colonnes et change en numérique uniquement celles qui sont logiques. Bien sûr, si vos TRUE et FALSE ne sont pas logiques mais que les chaînes de caractères (qui peuvent être à distance) mon code ne fonctionnera pas.

for(i in 1:ncol(dat)){

    if(is.logical(dat[, i]) == TRUE) dat[, i] <- as.numeric(dat[, i]) 

    }
9
SabDeM

S'il y a plusieurs colonnes, vous pouvez utiliser set (en utilisant l'exemple de @ josilber)

library(data.table)
Cols <-  which(sapply(dat, is.logical))
setDT(dat)

for(j in Cols){
 set(dat, i=NULL, j=j, value= as.numeric(dat[[j]]))
}
9
akrun

La façon la plus simple de le faire!

Multipliez votre matrice par 1

Par exemple:

A <- matrix(c(TRUE,FALSE,TRUE,TRUE,TRUE,FALSE,FALSE,TRUE),ncol=4)
A

# [ 1] [ 2] [ 3] [ 4]
# [1,] VRAI VRAI VRAI FAUX
# [2,] FAUX VRAI FAUX VRAI

B <- 1*A
B

# [ 1] [ 2] [ 3] [ 4]
# [1,] 1 1 1 0
# [2,] 0 1 0 1

(Vous pouvez également ajouter zéro: B <- 0+A)

6
user8091544

Comme Ted Harding l'a souligné dans la liste de diffusion R-help , une façon simple de convertir des objets logiques en numérique est d'effectuer une opération arithmétique sur eux. Les plus pratiques seraient * 1 Et + 0, Qui conserveront le paradigme VRAI/FAUX == 1/0.

Pour vos données factices (j'ai un peu changé le code pour utiliser des packages R réguliers et pour réduire la taille):

df    <- data.frame(cbind(1:10, rnorm(10) > 0))
df$X3 <- df$X2 == 1
df$X4 <- df$X2 != 1

L'ensemble de données que vous obtenez a un mélange de variables numériques et booléennes:

   X1 X2    X3    X4
1   1  0 FALSE  TRUE
2   2  0 FALSE  TRUE
3   3  1  TRUE FALSE
4   4  1  TRUE FALSE
5   5  1  TRUE FALSE
6   6  0 FALSE  TRUE
7   7  0 FALSE  TRUE
8   8  1  TRUE FALSE
9   9  0 FALSE  TRUE
10 10  1  TRUE FALSE

Maintenant, laisse

df2 <- 1 * df

(Si votre jeu de données contient des variables de caractère ou de facteur, vous devrez appliquer cette opération à un sous-ensemble de df filtrant ces variables)

df2 Est égal à

   X1 X2 X3 X4
1   1  0  0  1
2   2  0  0  1
3   3  1  1  0
4   4  1  1  0
5   5  1  1  0
6   6  0  0  1
7   7  0  0  1
8   8  1  1  0
9   9  0  0  1
10 10  1  1  0

Ce qui est 100% numérique, comme str(df2) vous le montrera.

Vous pouvez maintenant exporter en toute sécurité df2 Vers votre autre programme.

4
Waldir Leoncio