Replace logical values (TRUE / FALSE) with numeric (1 / 0)

前端 未结 6 587
傲寒
傲寒 2020-12-03 04:34

I am exporting data from R with the command:

write.table(output,file = "data.raw", na "-9999", sep = "\\t", row.names = FALSE, c         


        
相关标签:
6条回答
  • 2020-12-03 05:13

    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
    
    0 讨论(0)
  • 2020-12-03 05:14

    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)

    0 讨论(0)
  • 2020-12-03 05:14

    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]]))
    }
    
    0 讨论(0)
  • 2020-12-03 05:18

    One line solution

    Using the following code we take all the logical columns and make them numeric.

    library(magrittr)
    dat %<>% mutate_if(is.logical,as.numeric) 
    
    0 讨论(0)
  • 2020-12-03 05:23

    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.

    0 讨论(0)
  • 2020-12-03 05:34

    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]) 
    
        }
    
    0 讨论(0)
提交回复
热议问题