How can I replace TRUE and FALSE values with 1 and

2020-02-26 04:33发布

I am exporting data from R with the command:

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

that exports my data correctly, but it exports all of the logical variables as TRUE and FALSE.

I need to read the data into another program that can only process numeric values. Is there an efficient way to convert these to numeric 1s and 0s during the export? I have a large number of numeric variables, so I was hoping to automatically loop through all the variables in the data.table

I realize I could run simple sed script on the output data, but it seems like this should be straight forward to do from R.

Alternatively, my output object is a data.table. Is there an efficient way to convert all the logical variables in a data.table into numeric variables?

In case it is helpful, here is some code to generate a data.table with a logical variable in it (it is not a large number of logical variables, but enough to use on example code):

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

This seems like an easy question, but its throwing me off, so thank you for the help!

标签: r data.table
5条回答
一夜七次
2楼-- · 2020-02-26 05:13

As Ted Harding pointed out in the R-help mailing list, one easy way to convert logical objects to numeric is to perform an arithmetic operation on them. Convenient ones would be * 1 and + 0, which will keep the TRUE/FALSE == 1/0 paradigm.

For your mock data (I've changed the code a bit to use regular R packages and to reduce size):

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

The dataset you get has a mixture of numeric and boolean variables:

   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

Now let

df2 <- 1 * df

(If your dataset contains character or factor variables, you will need to apply this operation to a subset of df filtering out those variables)

df2 is equal to

   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

Which is 100% numeric, as str(df2) will show you.

Now you can safely export df2 to your other program.

查看更多
爷、活的狠高调
3楼-- · 2020-02-26 05:17

What about just a:

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

or another approach could be with dplyr in order to retain the previous column if the case (no one knows) your data will be imported in 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

Edit: Loop

I do not know if my code here is performing but it checks all column and change to numerical only those that are logical. Of course if your TRUE and FALSE are not logical but character strings (which might be remotely) my code won't work.

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

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

    }
查看更多
▲ chillily
4楼-- · 2020-02-26 05:19

Simplest way of doing this!

Multiply your matrix by 1

For example:

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

#       [,1]      [,2]      [,3]        [,4]
# [1,] TRUE  TRUE TRUE   FALSE
# [2,] FALSE TRUE FALSE TRUE

B <- 1*A
B

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

(You could also add zero: B <- 0+A)

查看更多
老娘就宠你
5楼-- · 2020-02-26 05:34

If there are multiple columns, you could use set (using @josilber's example)

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]]))
}
查看更多
戒情不戒烟
6楼-- · 2020-02-26 05:37

For a data.frame, you could convert all logical columns to numeric with:

# 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

In data.table syntax:

# 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
查看更多
登录 后发表回答