根据if语句对for循环进行分组,并添加新列

时间:2017-04-04 12:22:39

标签: r for-loop if-statement dataframe grouping

我有以下代码,我需要调整它,因为输出不是100%正确:

df = read.table(text='colA   colB   colC
                10  11   7
                10  34   7
                10  89   7
                10  21   7
                9   8    0
                9   11   0
                9   21   0
                2   23   5
                2   21   5
                2   56   5
                1   45   0
                1   23   0
                22  14   3
                22  19   3
                22  90   3
                11  19   2
                11  45   2
                80  13   2
                80  17   2
                99  15   1
                55  20   1', header = TRUE)

df$ID <-NA

df[1,'ID']<-1

val=1

for (i in 2:nrow(df)){

  if (df[i,'colC']!=0 & (df[i,'colC']!=df[i-1,'colC'])) {val=val+1} 
  df[i,'ID']<-val

}

按上述代码输出:

> df
   colA colB colC ID
1    10   11    7  1
2    10   34    7  1
3    10   89    7  1
4    10   21    7  1
5     9    8    0  1
6     9   11    0  1
7     9   21    0  1
8     2   23    5  2
9     2   21    5  2
10    2   56    5  2
11    1   45    0  2
12    1   23    0  2
13   22   14    3  3
14   22   19    3  3
15   22   90    3  3
16   11   19    2  4
17   11   45    2  4
18   80   13    2  4
19   80   17    2  4
20   99   15    1  5
21   55   20    1  5

最后4个ID值有什么问题,这些值应根据colC对行进行分组,但由于每个不同的组之间没有0,colC值的数字相同但是多样的colA被组合在一起,这不是我想要的。

期望的输出(参见最后4个ID值):

> df
   colA colB colC ID
1    10   11    7  1
2    10   34    7  1
3    10   89    7  1
4    10   21    7  1
5     9    8    0  1
6     9   11    0  1
7     9   21    0  1
8     2   23    5  2
9     2   21    5  2
10    2   56    5  2
11    1   45    0  2
12    1   23    0  2
13   22   14    3  3
14   22   19    3  3
15   22   90    3  3
16   11   19    2  4
17   11   45    2  4
18   80   13    2  5
19   80   17    2  5
20   99   15    1  6
21   55   20    1  7

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

您需要稍微改变一下条件,因为不同的colA值会产生新ID,colA需要包含在条件中:

for (i in 2:nrow(df)){   
    # check the difference of colA here
    if (df[i,'colC']!=0 & (df[i,'colA']!=df[i-1,'colA'])) {val=val+1} 
    df[i,'ID']<-val    
}

df$ID
# [1] 1 1 1 1 1 1 1 2 2 2 2 2 3 3 3 4 4 5 5 6 7

或者您可以将其矢量化为:

df$ID <- with(df, cumsum(c(TRUE, diff(colA) != 0 & colC[-1] != 0)))
df$ID
# [1] 1 1 1 1 1 1 1 2 2 2 2 2 3 3 3 4 4 5 5 6 7