Почему R удаляет имена векторов, извлеченных из матрицы из одного столбца с именованными строками? - PullRequest
2 голосов
/ 16 июня 2019

Я хочу взять одну строку матрицы M и обработать строку как именованный вектор, а имена столбцов исходной матрицы - как имена вектора. Обычно M[x, ] делает то, что я хочу, но это не работает, если: (а) строки матрицы названы, и (б) количество столбцов равно 1.

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

Примеры:

M <- structure(c(72L, 92L, 81L, 81L, 87L, 76L, 89L, 70L, 70L, 73L, 
74L, 75L), .Dim = 4:3, .Dimnames = list(c("SeptQuiz", "Midterm", 
"NovQuiz", "Final"), c("Anne", "Bo", "Cameron"))) # multiple columns, rows are named

(v1 <- M[3, ]) # subsetting one row, as a vector, preserves student names

M <- structure(c(91L, 87L, 83L, 81L), .Dim = c(4L, 1L), .Dimnames = list(
    NULL, "Frank")) # one column, rows are unnamed

(v1 <- M[3, ]) # again, subsetting one row as a vector preserves student name

M <- structure(c(91L, 87L, 83L, 81L), .Dim = c(4L, 1L), .Dimnames = list(
    c("SeptQuiz", "Midterm", "NovQuiz", "Final"), "Frank")) # one column, rows are named

(v1 <- M[3, ]) # subsetting one row deletes student name

if(ncol(M) == 1 && !is.null(rownames(M))) {names(v1) <- colnames(M)} # kludge to restore student name if it was stripped

1 Ответ

0 голосов
/ 16 июня 2019

Одной из целей имен строк может быть предоставление другого способа поднабора.Рассмотрим случай, когда вы хотите установить подмножество вашего первого M на основе SeptQuiz, который является первым именем строки.Вы можете сделать:

M <- structure(c(72L, 92L, 81L, 81L, 87L, 76L, 89L, 70L, 70L, 73L, 
                 74L, 75L), .Dim = 4:3, .Dimnames = list(c("SeptQuiz", "Midterm", 
                                                           "NovQuiz", "Final"), c("Anne", "Bo", "Cameron"))) # multiple columns, rows are named

    M["SeptQuiz", ]

, что эквивалентно действию:

M[1, ]

Возможно, более естественным способом (который не имеет отношения к вашему вопросу) было бы организовать это с помощьюимена студентов в виде строк и викторины в виде столбца.Темы лучше в строках и переменные в столбцах.

Другое использование имен строк может быть, когда вам нужно преобразовать M в именованный список строк.Например, в

sapply(rownames(M), function(i) M[i,], simplify = FALSE)

вы можете видеть, что результатом является именованный список, в котором каждому элементу присваиваются имена в соответствии с соответствующими именами строк.

Исходя из вашей проблемы, по умолчанию аргумент dropфункции подмножества установлен на TRUE, что означает, что результат будет приведен к наименьшему возможному измерению.см help( [).Вы можете увидеть эффект этого, сравнив результаты следующих двух строк кода:

M[3, , drop = TRUE] # rownames are dropped
M[3, ] # same as above. note the difference `, ,` in the first vs `,` here
M[3, drop = TRUE] # same as above.
M[3, drop = FALSE] # # same as above because no column is explicitly specified
M[3, , drop = FALSE] # rownames are kept

При этом попробуйте следующее:

M <- structure(c(91L, 87L, 83L, 81L), .Dim = c(4L, 1L), .Dimnames = list(
    NULL, "Frank")) # one column, rows are unnamed

(v1 <- M[3, ]) # again, subsetting one row as a vector preserves student name
class(v1) # vector
class(M) # matrix
(v1 <- M[,1]) # subseting the first column.
class (v1) # the result is a vector

Чтобы сохранить их, используйтеследующие

M <- structure(c(91L, 87L, 83L, 81L), .Dim = c(4L, 1L), .Dimnames = list(
    NULL, "Frank")) # one column, rows are unnamed

(v1 <- M[3, ,drop=FALSE]) # again, subsetting one row as a vector preserves student name

или

(v1 <- M[, 1, drop = FALSE]) 

Вы также можете увидеть различные значения в:

M <- structure(c(91L, 87L, 83L, 81L), .Dim = c(4L, 1L), .Dimnames = list(
    c("SeptQuiz", "Midterm", "NovQuiz", "Final"), "Frank")) # one column, rows are named

(v1 <- M[3, ]) # subsetting one row deletes student name
(v1 <- M[3, , drop = FALSE]) # subsetting one row does not delete student name

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

В

M <- structure(c(91L, 87L, 83L, 81L), .Dim = c(4L, 1L), .Dimnames = list(
    NULL, "Frank")) # one column, rows are unnamed
M [3, , drop = FALSE] # knows you want to keep colnames 

он знает васхочу сохранить имена столбцов, так как нет имен строк.Результатом будет одномерный вектор.Но в

M <- structure(c(91L, 87L, 83L, 81L), .Dim = c(4L, 1L), .Dimnames = list(
    c("SeptQuiz", "Midterm", "NovQuiz", "Final"), "Frank")) 
M[3, ] # would not know which one to keep

он не знает, хотите ли вы сохранить имена столбцов или строк в качестве имен для результирующего 1-мерного вектора, и результат будет не объединенным, так как 1-мерный вектор может не иметь смыслас двумя именами.

Если вы указали аргумент drop=FALSE как в

M <- structure(c(91L, 87L, 83L, 81L), .Dim = c(4L, 1L), .Dimnames = list(
    c("SeptQuiz", "Midterm", "NovQuiz", "Final"), "Frank")) 
M[3, , drop=FALSE] # would not know which one to drop

, он знает, что вы не хотите ничего отбрасывать, но 1-мерный вектор не может иметь 2имен, тогда результатом будет матрица.

Но, как указывалось в комментариях @Henrik: «Если результат - вектор длины один, имена берутся из первого измерения с dimname«.см ?drop

...