R - Как изменить элементы в матрице, начиная с указанной c точки - PullRequest
1 голос
/ 14 февраля 2020

У меня есть фрейм данных M, который выглядит следующим образом:

 [,1]      [,2]      [,3]       [,4]     [,5]
 [1,] 0.4212778 0.6874073 0.1551896 Cluster_1
 [2,] 0.6874073 0.5610995 0.1779030 Cluster_1
 [3,] 0.1551896 0.1779030 0.9515304 Cluster_1
 [4,] 0.4675764 0.5407295 0.7942978 Cluster_1_A
 [5,] 0.4675764 0.5407295 0.7942978 Cluster_1
 [6,] 0.4675764 0.5407295 0.7942978 Cluster_1
 [7,] 0.4675764 0.5407295 0.7942978 Cluster_2
 [8,] 0.4675764 0.5407295 0.7942978 Cluster_2_A
 [9,] 0.4675764 0.5407295 0.7942978 Cluster_2
[10,] 0.4675764 0.5407295 0.7942978 Cluster_2
[11,] 0.4675764 0.5407295 0.7942978 Cluster_2_1_A
[12,] 0.4675764 0.5407295 0.7942978 Cluster_2
[13,] 0.4675764 0.5407295 0.7942978 Cluster_2
[14,] 0.4675764 0.5407295 0.7942978 Cluster_3
[15,] 0.4675764 0.5407295 0.7942978 Cluster_3
[15,] 0.4675764 0.5407295 0.7942978 Cluster_3
[16,] 0.4675764 0.5407295 0.7942978 Cluster_4
[17,] 0.4675764 0.5407295 0.7942978 Cluster_4

Я хочу присвоить одно и то же имя элементам матрицы (столбец 5) в диапазоне, начиная с элемента с "_A "флаг до следующей смены имени. В этом случае:

  • от M [4,5] до элемента M [6,5]
  • от M [8,5] до элемента M [10,5]
  • от M [11,5] до элемента M [13,5]

Я хочу получить следующий результат:

 [,1]      [,2]      [,3]       [,4]     [,5]
 [1,] 0.4212778 0.6874073 0.1551896 Cluster_1
 [2,] 0.6874073 0.5610995 0.1779030 Cluster_1
 [3,] 0.1551896 0.1779030 0.9515304 Cluster_1
 [4,] 0.4675764 0.5407295 0.7942978 Cluster_1_A
 [5,] 0.4675764 0.5407295 0.7942978 Cluster_1_A
 [6,] 0.4675764 0.5407295 0.7942978 Cluster_1_A
 [7,] 0.4675764 0.5407295 0.7942978 Cluster_2
 [8,] 0.4675764 0.5407295 0.7942978 Cluster_2_A
 [9,] 0.4675764 0.5407295 0.7942978 Cluster_2_A
[10,] 0.4675764 0.5407295 0.7942978 Cluster_2_A
[11,] 0.4675764 0.5407295 0.7942978 Cluster_2_1_A
[12,] 0.4675764 0.5407295 0.7942978 Cluster_2_1_A
[13,] 0.4675764 0.5407295 0.7942978 Cluster_2_1_A
[14,] 0.4675764 0.5407295 0.7942978 Cluster_3
[15,] 0.4675764 0.5407295 0.7942978 Cluster_3
[15,] 0.4675764 0.5407295 0.7942978 Cluster_3
[16,] 0.4675764 0.5407295 0.7942978 Cluster_4
[17,] 0.4675764 0.5407295 0.7942978 Cluster_4

Как мне это сделать? что быстро, также избегая для l oop (который я могу кодировать)? Я видел много похожих постов, но никто не дал мне то, что я хочу. Спасибо!

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Вы можете попробовать что-то вроде этого, преобразовать ваш (который выглядит как матрица) в data.frame:

df = structure(list(value1 = c(0.4212778, 0.6874073, 0.1551896, 0.4675764, 
0.4675764, 0.4675764, 0.4675764, 0.4675764, 0.4675764, 0.4675764, 
0.4675764, 0.4675764, 0.4675764, 0.4675764, 0.4675764, 0.4675764, 
0.4675764, 0.4675764), value2 = c(0.6874073, 0.5610995, 0.177903, 
0.5407295, 0.5407295, 0.5407295, 0.5407295, 0.5407295, 0.5407295, 
0.5407295, 0.5407295, 0.5407295, 0.5407295, 0.5407295, 0.5407295, 
0.5407295, 0.5407295, 0.5407295), value3 = c(0.1551896, 0.177903, 
0.9515304, 0.7942978, 0.7942978, 0.7942978, 0.7942978, 0.7942978, 
0.7942978, 0.7942978, 0.7942978, 0.7942978, 0.7942978, 0.7942978, 
0.7942978, 0.7942978, 0.7942978, 0.7942978), cluster = structure(c(1L, 
1L, 1L, 2L, 1L, 1L, 3L, 5L, 3L, 3L, 4L, 3L, 3L, 6L, 6L, 6L, 7L, 
7L), .Label = c("Cluster_1", "Cluster_1_A", "Cluster_2", "Cluster_2_1_A", 
"Cluster_2_A", "Cluster_3", "Cluster_4"), class = "factor")), class = "data.frame", row.names = c(NA, 
-18L))

head(df)

     value1    value2    value3     cluster
1 0.4212778 0.6874073 0.1551896   Cluster_1
2 0.6874073 0.5610995 0.1779030   Cluster_1
3 0.1551896 0.1779030 0.9515304   Cluster_1
4 0.4675764 0.5407295 0.7942978 Cluster_1_A
5 0.4675764 0.5407295 0.7942978   Cluster_1
6 0.4675764 0.5407295 0.7942978   Cluster_1

Если мы сделаем следующее:

df$id = as.numeric(factor(df$cluster))

head(df,10)
      value1    value2    value3     cluster id
1  0.4212778 0.6874073 0.1551896   Cluster_1  1
2  0.6874073 0.5610995 0.1779030   Cluster_1  1
3  0.1551896 0.1779030 0.9515304   Cluster_1  1
4  0.4675764 0.5407295 0.7942978 Cluster_1_A  2
5  0.4675764 0.5407295 0.7942978   Cluster_1  1
6  0.4675764 0.5407295 0.7942978   Cluster_1  1
7  0.4675764 0.5407295 0.7942978   Cluster_2  3
8  0.4675764 0.5407295 0.7942978 Cluster_2_A  5
9  0.4675764 0.5407295 0.7942978   Cluster_2  3
10 0.4675764 0.5407295 0.7942978   Cluster_2  3

Вы можно видеть каждый раз, когда происходит увеличение, т.е. с 1 до 2 в строке 3: 4 или с 3 до 5 в строке 7: 8, это то место, где мы хотим их разделить. Итак, мы делаем это:

df$grp = cumsum(c(0,diff(df$id)>0))

      value1    value2    value3     cluster id grp
1  0.4212778 0.6874073 0.1551896   Cluster_1  1   0
2  0.6874073 0.5610995 0.1779030   Cluster_1  1   0
3  0.1551896 0.1779030 0.9515304   Cluster_1  1   0
4  0.4675764 0.5407295 0.7942978 Cluster_1_A  2   1
5  0.4675764 0.5407295 0.7942978   Cluster_1  1   1
6  0.4675764 0.5407295 0.7942978   Cluster_1  1   1
7  0.4675764 0.5407295 0.7942978   Cluster_2  3   2
8  0.4675764 0.5407295 0.7942978 Cluster_2_A  5   3
9  0.4675764 0.5407295 0.7942978   Cluster_2  3   3

Ваш новый идентификатор просто:

df$new = unlist(
tapply(as.character(df$cluster),
df$grp,
function(i)rep(i[1],length(i))))

      value1    value2    value3       cluster id grp           new
1  0.4212778 0.6874073 0.1551896     Cluster_1  1   0     Cluster_1
2  0.6874073 0.5610995 0.1779030     Cluster_1  1   0     Cluster_1
3  0.1551896 0.1779030 0.9515304     Cluster_1  1   0     Cluster_1
4  0.4675764 0.5407295 0.7942978   Cluster_1_A  2   1   Cluster_1_A
5  0.4675764 0.5407295 0.7942978     Cluster_1  1   1   Cluster_1_A
6  0.4675764 0.5407295 0.7942978     Cluster_1  1   1   Cluster_1_A
7  0.4675764 0.5407295 0.7942978     Cluster_2  3   2     Cluster_2
8  0.4675764 0.5407295 0.7942978   Cluster_2_A  5   3   Cluster_2_A
9  0.4675764 0.5407295 0.7942978     Cluster_2  3   3   Cluster_2_A
10 0.4675764 0.5407295 0.7942978     Cluster_2  3   3   Cluster_2_A
11 0.4675764 0.5407295 0.7942978 Cluster_2_1_A  4   4 Cluster_2_1_A
12 0.4675764 0.5407295 0.7942978     Cluster_2  3   4 Cluster_2_1_A
13 0.4675764 0.5407295 0.7942978     Cluster_2  3   4 Cluster_2_1_A
14 0.4675764 0.5407295 0.7942978     Cluster_3  6   5     Cluster_3
15 0.4675764 0.5407295 0.7942978     Cluster_3  6   5     Cluster_3
16 0.4675764 0.5407295 0.7942978     Cluster_3  6   5     Cluster_3
17 0.4675764 0.5407295 0.7942978     Cluster_4  7   6     Cluster_4
18 0.4675764 0.5407295 0.7942978     Cluster_4  7   6     Cluster_4
1 голос
/ 14 февраля 2020

Ниже вы можете попробовать базовое решение R, которое применило ave + gsub

M <- within(M,V5 <- ave(V5,
                          gsub("(Cluster_\\d+).*","\\1",V5), 
                          FUN = function(x) ave(x,
                                                cumsum(grepl("_A",x)),
                                                FUN = function(q) head(q,1))))

так, что

> M
      V1        V2        V3        V4            V5
1   [1,] 0.4212778 0.6874073 0.1551896     Cluster_1
2   [2,] 0.6874073 0.5610995 0.1779030     Cluster_1
3   [3,] 0.1551896 0.1779030 0.9515304     Cluster_1
4   [4,] 0.4675764 0.5407295 0.7942978   Cluster_1_A
5   [5,] 0.4675764 0.5407295 0.7942978   Cluster_1_A
6   [6,] 0.4675764 0.5407295 0.7942978   Cluster_1_A
7   [7,] 0.4675764 0.5407295 0.7942978     Cluster_2
8   [8,] 0.4675764 0.5407295 0.7942978   Cluster_2_A
9   [9,] 0.4675764 0.5407295 0.7942978   Cluster_2_A
10 [10,] 0.4675764 0.5407295 0.7942978   Cluster_2_A
11 [11,] 0.4675764 0.5407295 0.7942978 Cluster_2_1_A
12 [12,] 0.4675764 0.5407295 0.7942978 Cluster_2_1_A
13 [13,] 0.4675764 0.5407295 0.7942978 Cluster_2_1_A
14 [14,] 0.4675764 0.5407295 0.7942978     Cluster_3
15 [15,] 0.4675764 0.5407295 0.7942978     Cluster_3
16 [15,] 0.4675764 0.5407295 0.7942978     Cluster_3
17 [16,] 0.4675764 0.5407295 0.7942978     Cluster_4
18 [17,] 0.4675764 0.5407295 0.7942978     Cluster_4

ДАННЫЕ

M <- structure(list(V1 = c("[1,]", "[2,]", "[3,]", "[4,]", "[5,]", 
"[6,]", "[7,]", "[8,]", "[9,]", "[10,]", "[11,]", "[12,]", "[13,]", 
"[14,]", "[15,]", "[15,]", "[16,]", "[17,]"), V2 = c(0.4212778, 
0.6874073, 0.1551896, 0.4675764, 0.4675764, 0.4675764, 0.4675764, 
0.4675764, 0.4675764, 0.4675764, 0.4675764, 0.4675764, 0.4675764, 
0.4675764, 0.4675764, 0.4675764, 0.4675764, 0.4675764), V3 = c(0.6874073, 
0.5610995, 0.177903, 0.5407295, 0.5407295, 0.5407295, 0.5407295, 
0.5407295, 0.5407295, 0.5407295, 0.5407295, 0.5407295, 0.5407295, 
0.5407295, 0.5407295, 0.5407295, 0.5407295, 0.5407295), V4 = c(0.1551896, 
0.177903, 0.9515304, 0.7942978, 0.7942978, 0.7942978, 0.7942978, 
0.7942978, 0.7942978, 0.7942978, 0.7942978, 0.7942978, 0.7942978, 
0.7942978, 0.7942978, 0.7942978, 0.7942978, 0.7942978), V5 = c("Cluster_1", 
"Cluster_1", "Cluster_1", "Cluster_1_A", "Cluster_1", "Cluster_1", 
"Cluster_2", "Cluster_2_A", "Cluster_2", "Cluster_2", "Cluster_2_1_A", 
"Cluster_2", "Cluster_2", "Cluster_3", "Cluster_3", "Cluster_3", 
"Cluster_4", "Cluster_4")), class = "data.frame", row.names = c(NA, 
-18L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...