0

I have a question about assigning a very wide range of numbers based on conditions in other columns.

In simple example I can describe my problem like this

df <- data.frame(col=rep(seq(0,3),each=4), row = c(seq(0,3)))

> df
   col row
1    0   0
2    0   1
3    0   2
4    0   3
5    1   0
6    1   1
7    1   2
8    1   3
9    2   0
10   2   1
11   2   2
12   2   3
13   3   0
14   3   1
15   3   2
16   3   3

I would like to create a new column based on the conditions in col and row column such that

assign_z <- function(col,row){

    ifelse(col==0&row<=0, 0, #0 is the assigned number to assign_z column
    ifelse(col==0&row>0&row<=2, 1, #1 is the assigned number to assign_z column
    ifelse(col==0&row>=3,2,        #2 is the assigned number to assign_z column

    ifelse(col==1&row<=0,3,        #3 is the assigned number to assign_z column
    ifelse(col==1&row>0&row<=2,4,  #4 is the assigned number to assign_z column
    ifelse(col==1&row>=3,5,        #5 is the assigned number to assign_z column

    ifelse(col==2&row<=0,6,        #6 is the assigned number to assign_z column 
    ifelse(col==2&row>0&row<=2,7,  #7 is the assigned number to assign_z column
    ifelse(col==2&row>=3,8,        #8 is the assigned number to assign_z column


    ifelse(col==3&row<=0,9,        #9 is the assigned number to assign_z column
    ifelse(col==3&row>0&row<=2,10, #10 is the assigned number to assign_z column 
    ifelse(col==3&row>=3,11,NA     #11 is the assigned number to assign_z column

    ))))))))))))

  }    
}

and when I run my function I can get

library(dplyr)

df%>%
  mutate(assign_z=assign_z(col,row))

   col row assign_z
1    0   0        0
2    0   1        1
3    0   2        1
4    0   3        2
5    1   0        3
6    1   1        4
7    1   2        4
8    1   3        5
9    2   0        6
10   2   1        7
11   2   2        7
12   2   3        8
13   3   0        9
14   3   1       10
15   3   2       10
16   3   3       11

but assign_z function will be too long as I have 1000 col number in my real data. In addition, assign_z column should be increased in this systematical manner.

How can shorten the function to create same result even if I have 1000 columns ?

cmaher
  • 5,100
  • 1
  • 22
  • 34
Alexander
  • 4,527
  • 5
  • 51
  • 98
  • `c(seq(0,3))` is just an obfuscated way of saying `0:3`. Hence `data.frame(col=rep(0:3, each=4), row=0:3)` – smci Apr 28 '18 at 01:53
  • @Alexander ... just ignoring that you asked this question and opening a new one now? https://stackoverflow.com/questions/50106253/setting-multiple-if-statements-correctly – AidanGawronski May 09 '18 at 14:50

2 Answers2

1

This performs a dense rank over the combination of col, row, but treats row = 2 as 1. I don't know what you are trying to achieve but it reproduces your output and would work with any length dataframe:

assign_z <- function(col, row){
  rank_over = paste0(col, ifelse(row == 2, 1, row))
  final_column = dense_rank(rank_over) - 1
  return(final_column)
}


df %>% mutate(assign_z=assign_z(col,row))
# col row assign_z
# 1    0   0        0
# 2    0   1        1
# 3    0   2        1
# 4    0   3        2
# 5    1   0        3
# 6    1   1        4
# 7    1   2        4
# 8    1   3        5
# 9    2   0        6
# 10   2   1        7
# 11   2   2        7
# 12   2   3        8
# 13   3   0        9
# 14   3   1       10
# 15   3   2       10
# 16   3   3       11
AidanGawronski
  • 2,055
  • 1
  • 14
  • 24
0

I don't use R, but based on what I see, can't you use a global counter please forgive any syntax issues

    counter <<- 0

    assign_z <- function(col,row){
        #get current value
        returnValue<-counter

        #add to counter if row = 0 or 2 or 3    
        if(row==0|row==2|row==3) { counter <<- counter + 1 }

        #return value before it was incremented
        return(returnValue)
    }

The pattern seems to be the number increment on row = 0, 2, 3