R: Извлекать значения с одинаковыми именами строк и заголовков

#r #matrix

#r #матрица

Вопрос:

Я пытаюсь извлечь значения (из таблицы), которые имеют одинаковые заголовки строк и столбцов. Например, у меня есть таблица, подобная этой:

     A   B   B   C   D   E   E
A   1   2   3   4   5   6   7
B   8   9   10  11  12  13  14  
C   15  16  17  18  19  20  21
D   22  23  24  25  26  27  28
E   29  30  31  32  33  34  35
  

И я хочу извлечь значения, чтобы получить что-то вроде этого:

 A   1
B   9
B   10
C   18
D   26
E   34
E   35
  

Есть идеи о том, как я мог бы это сделать? Это должно работать для любого количества строк и столбцов, и может быть более двух столбцов с одинаковыми заголовками.

Комментарии:

1. структура(c(1L, 8L, 15L, 22L, 29L, 2L, 9L, 16L, 23L, 30L, 3L, 10L, 17L, 24L, 31L, 4L, 11L, 18L, 25L, 32L, 5L, 12L, 19L, 26L, 33L, 6L, 13L, 20L, 27L, 34L, 7L, 14L, 21L, 28L, 35L ), .Dim = c(5L, 7L), .Dimnames = список(c(«A», «B», «C», «D», «E»), c(«A», «B», «B.1», «C», «D», «E», «E.1»)))

2. почему понижающий голос?

Ответ №1:

Вы можете sapply просмотреть имена строк / столбцов, чтобы проверить равенство, а затем использовать этот индекс для сборки данных.frame:

 i <- sapply(colnames(mat), `==`, rownames(mat))    # or i <- outer(rownames(mat), colnames(mat), `==`)

i
##          A     B     B     C     D     E     E
## [1,]  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
## [2,] FALSE  TRUE  TRUE FALSE FALSE FALSE FALSE
## [3,] FALSE FALSE FALSE  TRUE FALSE FALSE FALSE
## [4,] FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
## [5,] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE

df <- data.frame(name = colnames(mat)[colSums(i) > 0],    # if unsure of dimensions, name = if(nrow(mat) > ncol(mat)){rownames(mat)[rowSums(i) > 0]}else{colnames(mat)[colSums(i) > 0]}
                 value = mat[i])

df
##   name value
## 1    A     1
## 2    B     9
## 3    B    10
## 4    C    18
## 5    D    26
## 6    E    34
## 7    E    35
  

Данные

 mat <- structure(c(1L, 8L, 15L, 22L, 29L, 2L, 9L, 16L, 23L, 30L, 3L, 
    10L, 17L, 24L, 31L, 4L, 11L, 18L, 25L, 32L, 5L, 12L, 19L, 26L, 
    33L, 6L, 13L, 20L, 27L, 34L, 7L, 14L, 21L, 28L, 35L), .Dim = c(5L, 
    7L), .Dimnames = list(c("A", "B", "C", "D", "E"), c("A", "B", 
    "B", "C", "D", "E", "E")))
  

Комментарии:

1. Спасибо за ваш ответ, но по какой-то причине, когда я пытаюсь это сделать, он не выдает мне оба значения для B и E, только одно

2. Ваша dput часть ваших данных показывает разные имена столбцов, чем пример в вопросе, который, я думаю, является проблемой. Посмотрите пример данных в моей правке, который соответствует тому, что в вопросе.

3. Я вижу, как B.1 и E.1, вы знаете, как это предотвратить?

4. Я имею в виду, как предотвратить добавление имен столбцов «.1», если при загрузке данных в R есть дубликаты?

5. R не любит повторяющихся имен. Вы можете переопределить их вручную, задав имена с помощью dimnames()<- или rownames()<- и colnames()<- . Если они соответствуют шаблону, вы можете gsub их удалить.

Ответ №2:

 tab = structure(c(1L, 8L, 15L, 22L, 29L, 2L, 9L, 16L, 23L, 30L, 3L, 10L, 17L, 24L, 31L, 4L, 11L, 18L, 25L, 32L, 5L, 12L, 19L, 26L, 33L, 6L, 13L, 20L, 27L, 34L, 7L, 14L, 21L, 28L, 35L), .Dim = c(5L, 7L), .Dimnames = list(c("A", "B", "C", "D", "E"), c("A", "B", "B", "C", "D", "E", "E"))) 
cols = colnames(tab)[col(tab)]
rows = rownames(tab)[row(tab)]
ind = (cols == rows)
a = tab[ind]
names(a) = cols[ind]