coderX
coderX

Reputation: 474

Conditional Output based on Column Values

I have a data frame (shown below) in which I'd like to add a column (ZZZ) which will produce an output depending on a couple of things. ID number, as can be seen, is a number 1-10. If ID is 9,10,1,2, I would like ZZZ to output only the value of XXX that corresponds to the ID number 9, but for all 4 of 9,10,1,2.

My df:

Name    XXX  ID
Marie   1144 9
Sarah   1433 10
Tim     1888 1
Nick    1787 2
James   1989 3
Mike    1345 4
Cate    1654 5
Rob     1365 6
Diane   1688 7
Jill    1993 8
Kathy   1723 9
Ken     1313 10
John    1111 1
George  1222 2
Frank   1333 3
Nancy   1444 4
Paul    1211 5
Henry   1311 6
Sue     1411 7
Jack    1522 8

This is the code that I have tried. Obviously, the code does not answer the second part of what I want. It will take the XXX that corresponds to each ID, rather than just 9.

ifelse(df, XXX %in% c(9,10,1,2),
        df$zzz=xxx, else df$zzz=NA)

I just do not know how to call out the specific FIRST xxx of each new repetition of ID numbers.

Want:

Name    XXX  ID ZZZ
Marie   1144 9  1144
Sarah   1433 10 1144
Tim     1888 1  1144
Nick    1787 2  1144
James   1989 3  NA
Mike    1345 4  NA
Cate    1654 5  NA
Rob     1365 6  NA
Diane   1688 7  NA
Jill    1993 8  NA
Kathy   1723 9  1723
Ken     1313 10 1723
John    1111 1  1723
George  1222 2  1723
Frank   1333 3  NA
Nancy   1444 4  NA
Paul    1211 5  NA
Henry   1311 6  NA
Sue     1411 7  NA
Jack    1522 8  NA

Upvotes: 1

Views: 83

Answers (1)

akrun
akrun

Reputation: 886938

We can use rollapply from library(zoo) to create a logical index. It works by checking each element followed by the next 3 elements to be 9, 10, 1, and 2. Such elements become TRUE in r and others become FALSE. m is the position of the most recent TRUE and count is the number of elements since the most recent TRUE. If we are within 4 of the most recent TRUE then pick the XXX at the corresponding position in m and otherwise NA:

library(zoo)

r <- rollapply(df$ID, 4, FUN = function(x) all(x==c(9,10, 1, 2)), 
        align = "left", fill = FALSE)
m <- match(cumsum(r), cumsum(r))
count <- seq_along(r) - m
transform(df, ZZZ = XXX[ifelse(count < 4, m, NA)])

#     Name  XXX ID  ZZZ
#1   Marie 1144  9 1144
#2   Sarah 1433 10 1144
#3     Tim 1888  1 1144
#4    Nick 1787  2 1144
#5   James 1989  3   NA
#6    Mike 1345  4   NA
#7    Cate 1654  5   NA
#8     Rob 1365  6   NA
#9   Diane 1688  7   NA
#10   Jill 1993  8   NA
#11  Kathy 1723  9 1723
#12    Ken 1313 10 1723
#13   John 1111  1 1723
#14 George 1222  2 1723
#15  Frank 1333  3   NA
#16  Nancy 1444  4   NA
#17   Paul 1211  5   NA
#18  Henry 1311  6   NA
#19    Sue 1411  7   NA
#20   Jack 1522  8   NA

Upvotes: 2

Related Questions