0

Im trying to write a function with nested if-else in R. How can I convert a data.frame where the values of columns are set to:

Input

 df <- read.table(header = TRUE, text="Chr     start       end        num    seg.mean    seg.mean.1   seg.mean.2
    1   68580000    68640000    A8430    0.7000      0     0.1032 
    1   115900000   116260000   B8430    0.0039      2.7202     2.7202
    1   173500000   173680000   C5      -1.7738      -2.0746    -0.2722")

condition:  
     x > 0 & x< 1      : 1
     x >= 1            : 2
     x < 0 & x > - 1   : -1
     x <= -1           : -2
     x = 0             : 0

expected output

    df <- read.table(header = TRUE, text="Chr     start       end        num    seg.mean    seg.mean.1   seg.mean.2
    1   68580000    68640000    A8430    1      0     1 
    1   115900000   116260000   B8430    1      2     2
    1   173500000   173680000   C5      -2      -2   -1")



fun_cond <- function(x) { ifelse( x >= 1, 2,ifelse( x > 0 & x < 1, 1),ifelse( x <= 1, 2,ifelse( x < 0 & x > -1, -1)))}
new_df[5:length(df)] <- lapply(new_df[5:length(df)], fun_cond)
989
  • 12,579
  • 5
  • 31
  • 53
beginner
  • 411
  • 1
  • 5
  • 13

2 Answers2

1

I think what you want is this:

  x = c(-1, 1, 0, 0, 1, -1, 0.5, 0.3, -0.4)
  fun_cond(x)

  fun_cond <- function(x){
    ifelse(x >= 1, 2, ifelse(x < 1 & x > 0, 1, ifelse(x < 0 & x > -1, -1, -2)))
  }

> fun_cond(x)
#[1] -2  2 -2 -2  2 -2  1  1 -1

Try it out...

Note that x == 0 is -2. There is no x <= 0 ... or x >= 0 ... expression like you described it.

If you want 0 as zero then use:

x = c(-1,1,0,0,1,-1,0.5,0.3, -0.4)
fun_cond(x)

fun_cond <- function(x){
  ifelse(x >= 1, 2, ifelse(x < 1 & x > 0, 1, ifelse( x == 0, 0, ifelse(x < 0 & x > -1, -1, -2))))
}

> fun_cond(x)
#[1] -2  2  0  0  2 -2  1  1 -1
Timo Wagner
  • 406
  • 4
  • 10
1

Try cut in base R:

cols <- grep("seg.mean", names(df))
res <- sapply(cols, function(i) 
                     cut(df[,i], breaks = c(-Inf, -1, 0, 1, Inf), labels = c(-2,-1,1,2)))

# to leave zeros untouched
res[df[cols]==0] <- 0

If you want to get your expected output:

df[cols] <- res

  # Chr     start       end   num seg.mean seg.mean.1 seg.mean.2
# 1   1  68580000  68640000 A8430        1          0          1
# 2   1 115900000 116260000 B8430        1          2          2
# 3   1 173500000 173680000    C5       -2         -2         -1
989
  • 12,579
  • 5
  • 31
  • 53