Кластеризация строк по группам на основе значения столбца с условиями - PullRequest
0 голосов
/ 26 июня 2018

Несколько дней назад я открыл эту тему:

Кластеризация строк по группам на основе значения столбца

В котором мы получили этот результат:

df <- data.frame(ID = c(1,1,1,1,1,1,1,1,1,1,1, 1, 1,1,1,1,1),
      Obs1 = c(1,1,0,1,0,1,1,0,1,0,0,0,1,1,1,1,1),
      Control = c(0,3,3,1,12,1,1,1,36,13,1,1,2,24,2,2,48),
      ClusterObs1 = c(1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5))

С:

df <- df %>% 
group_by(ID) %>% 
mutate_at(vars(Obs1), 
        funs(ClusterObs1= with(rle(.), rep(cumsum(values == 1), lengths))))

Теперь я должен внести некоторые изменения:

Если значение «Control» больше 12, а фактическое значение «Obs1» равно 1 и предыдущему значению «Obs1», значение «DesiredResultClusterObs1» должно добавить +1

df <- data.frame(ID = c(1,1,1,1,1,1,1,1,1,1,1, 1, 1,1,1,1,1),
      Obs1 = c(1,1,0,1,0,1,1,0,1,0,0,0,1,1,1,1,1),
      Control = c(0,3,3,1,12,1,1,1,36,13,1,1,2,24,2,2,48),
      ClusterObs1 = c(1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5),
      DesiredResultClusterObs1 = c(1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 6, 6, 6, 7))

Я подумал добавить условие if_else с задержкой в ​​шутках, но безуспешно, есть идеи?

РЕДАКТИРОВАТЬ: Как это будет для многих столбцов?

1 Ответ

0 голосов
/ 26 июня 2018

Это похоже на работу:

df %>%
  mutate(DesiredResultClusterOrbs1 = with(rle(Control > 12 & Obs1 == 1 & lag(Obs1) == 1),
                                              rep(cumsum(values == 1), lengths)) + ClusterObs1)

   ID Obs1 Control ClusterObs1 DesiredResultClusterOrbs1
1   1    1       0           1                         1
2   1    1       3           1                         1
3   1    0       3           1                         1
4   1    1       1           2                         2
5   1    0      12           2                         2
6   1    1       1           3                         3
7   1    1       1           3                         3
8   1    0       1           3                         3
9   1    1      36           4                         4
10  1    0      13           4                         4
11  1    0       1           4                         4
12  1    0       1           4                         4
13  1    1       2           5                         5
14  1    1      24           5                         6
15  1    1       2           5                         6
16  1    1       2           5                         6
17  1    1      48           5                         7

В основном, мы используем механику rle + rep из вашего предыдущего потока, чтобы создать кумулятивный вектор из результата TRUE/FALSE ваших условий и добавить его к существующему ClusterObs1.


Если вы хотите создать несколько DesiredResultClusterOrbs, вы можете использовать mapply. Может быть, dplyr решение для этого, но это базовая R.

Данные:

df <- data.frame(ID = c(1,1,1,1,1,1,1,1,1,1,1, 1, 1,1,1,1,1),
                 Obs1 = c(1,1,0,1,0,1,1,0,1,0,0,0,1,1,1,1,1),
                 Obs2 = rbinom(17, 1, .5),
                 Control = c(0,3,3,1,12,1,1,1,36,13,1,1,2,24,2,2,48),
                 ClusterObs1 = c(1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5))

df <- df %>%
  mutate_at(vars(Obs2), 
            funs(ClusterObs2= with(rle(.), rep(cumsum(values == 1), lengths))))

Цикл:

newcols <- mapply(function(x, y){
  with(rle(df$Control > 12 & x == 1 & lag(x) == 1),
       rep(cumsum(values == 1), lengths)) + y
}, df[2:3], df[5:6])

Создает матрицу с новыми столбцами, которые затем можно переименовать и cbind для ваших данных:

colnames(newcols) <- paste0("DesiredResultClusterOrbs", 1:2)

cbind.data.frame(df, newcols)

   ID Obs1 Obs2 Control ClusterObs1 ClusterObs2 DesiredResultClusterOrbs1 DesiredResultClusterOrbs2
1   1    1    1       0           1           1                         1                         1
2   1    1    1       3           1           1                         1                         1
3   1    0    0       3           1           1                         1                         1
4   1    1    0       1           2           1                         2                         1
5   1    0    0      12           2           1                         2                         1
6   1    1    0       1           3           1                         3                         1
7   1    1    1       1           3           2                         3                         2
8   1    0    0       1           3           2                         3                         2
9   1    1    1      36           4           3                         4                         3
10  1    0    1      13           4           3                         4                         4
11  1    0    0       1           4           3                         4                         4
12  1    0    1       1           4           4                         4                         5
13  1    1    1       2           5           4                         5                         5
14  1    1    0      24           5           4                         6                         5
15  1    1    1       2           5           5                         6                         6
16  1    1    1       2           5           5                         6                         6
17  1    1    1      48           5           5                         7                         7
...