generate column values with multiple conditions in R

后端 未结 8 1999
甜味超标
甜味超标 2020-12-29 00:22

I have a dataframe z and I want to create the new column based on the values of two old columns of z. Following is the process:

&g         


        
相关标签:
8条回答
  • 2020-12-29 00:35

    Based on the suggestion of Señor :

    > z$q <- ifelse(z$x == 2, z$t * 2,
             ifelse(z$x == 4, z$t * 4,
             ifelse(z$x == 7, z$t * 3,
                              z$t * 1)))
    > z
        x  y  t  q
    1   1 11 21 21
    2   2 12 22 44
    3   3 13 23 23
    4   4 14 24 96
    5   5 15 25 25
    6   6 16 26 26
    7   7 17 27 81
    8   8 18 28 28
    9   9 19 29 29
    10 10 20 30 30
    
    0 讨论(0)
  • 2020-12-29 00:39

    I really liked the answer "dinre" posted to flodel's blog:

    for (i in 1:length(data_Array)){
    data_Array[i] <- switch(data_Array[i], banana="apple", orange="pineapple", "fig")
    }
    

    With warnings about reading the help page for switch carefully for integer arguments.

    0 讨论(0)
  • 2020-12-29 00:42

    By building a nested ifelse functional by recursion, you can get the benefits of both solutions offered so far: ifelse is fast and can work with any type of data, while @Matthew's solution is more functional yet limited to integers and potentially slow.

    decode <- function(x, search, replace, default = NULL) {
    
       # build a nested ifelse function by recursion
       decode.fun <- function(search, replace, default = NULL)
          if (length(search) == 0) {
             function(x) if (is.null(default)) x else rep(default, length(x))
          } else {
             function(x) ifelse(x == search[1], replace[1],
                                                decode.fun(tail(search, -1),
                                                           tail(replace, -1),
                                                           default)(x))
          }
    
       return(decode.fun(search, replace, default)(x))
    }
    

    Note how the decode function is named after the SQL function. I wish a function like this made it to the base R package... Here are a couple examples illustrating its usage:

    decode(x = 1:5, search = 3, replace = -1)
    # [1]  1  2 -1  4  5
    decode(x = 1:5, search = c(2, 4), replace = c(20, 40), default = 3)
    # [1] 3 20  3  40  3
    

    For your particular problem:

    transform(z, q = decode(x, search = c(2,4,7), replace = c(2,4,3), default = 1) * t)
    
    #    x  y  t  q
    # 1   1 11 21 21
    # 2   2 12 22 44
    # 3   3 13 23 23
    # 4   4 14 24 96
    # 5   5 15 25 25
    # 6   6 16 26 26
    # 7   7 17 27 81
    # 8   8 18 28 28
    # 9   9 19 29 29
    # 10 10 20 30 30
    
    0 讨论(0)
  • 2020-12-29 00:43

    Here is an easy solution with just one ifelse command:

    Calculate the multiplier of t:

    ifelse(z$x == 7, 3, z$x ^ (z$x %in% c(2, 4)))
    

    The complete command:

    transform(z, q = t * ifelse(x == 7, 3, x ^ (x %in% c(2, 4))))
    
        x  y  t  q
    1   1 11 21 21
    2   2 12 22 44
    3   3 13 23 23
    4   4 14 24 96
    5   5 15 25 25
    6   6 16 26 26
    7   7 17 27 81
    8   8 18 28 28
    9   9 19 29 29
    10 10 20 30 30
    
    0 讨论(0)
  • 2020-12-29 00:44

    You can also use match to do this. I tend to use this a lot while assigning parameters like col, pch and cex to points in scatterplots

    searchfor<-c(2,4,7)
    replacewith<-c(2,4,3)
    
    # generate multiplier column
    # q could also be an existing vector where you want to replace certain entries
    q<-rep(1,nrow(z))
    #
    id<-match(z$x,searchfor)
    id<-replacewith[id]
    # Apply the matches to q
    q[!is.na(id)]<-id[!is.na(id)]
    # apply to t
    z$q<-q*z$t
    
    0 讨论(0)
  • 2020-12-29 00:46

    You can do it in

    • base R
    • with one line
    • in which the mapping is pretty clear to read in the code
    • no helper functions (ok, an anonymous function)
    • approach works with negatives
    • approach works with any atomic vector (reals, characters)

    like this:

    > transform(z,q=t*sapply(as.character(x),function(x) switch(x,"2"=2,"4"=4,"7"=3,1)))
        x  y  t  q
    1   1 11 21 21
    2   2 12 22 44
    3   3 13 23 23
    4   4 14 24 96
    5   5 15 25 25
    6   6 16 26 26
    7   7 17 27 81
    8   8 18 28 28
    9   9 19 29 29
    10 10 20 30 30
    
    0 讨论(0)
提交回复
热议问题