基于列值的条件输出

时间:2015-10-29 16:44:58

标签: r

我有一个数据框(如下所示),其中我想添加一个列(ZZZ),它将产生一个输出,具体取决于几个方面。可以看出,ID号是1-10。如果ID是9,10,1,2,我希望ZZZ只输出对应于ID号9的XXX的值,但是对于9,10,1,2的所有4个。

我的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

这是我尝试过的代码。显然,代码没有回答我想要的第二部分。它将采用与每个ID相对应的XXX,而不仅仅是9。

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

我只是不知道如何调出每个新重复身份证号码的具体FIRST xxx。

想要:

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

1 个答案:

答案 0 :(得分:2)

我们可以使用rollapply中的library(zoo来创建逻辑索引。它的工作原理是检查每个元素,然后检查接下来的3个元素是9,10,1和2.这些元素在r中变为TRUE,而其他元素变为FALSE。 m是最近的TRUE的位置,count是自最近的TRUE以来的元素数。如果我们在最近的TRUE中的4个之内,那么在XXX中的相应位置选择m,否则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