Я заметил, что если имена строк фрейма данных следуют за последовательностью чисел от 1 до количества строк. Имена строк фрейма данных исчезнут после использования as.matrix
. Но имена строк появляются снова, если имя строки не является последовательностью.
Вот воспроизводимый пример:
test <- as.data.frame(list(x=c(0.1, 0.1, 1), y=c(0.1, 0.2, 0.3)))
rownames(test)
# [1] "1" "2" "3"
rownames(as.matrix(test))
# NULL
rownames(as.matrix(test[c(1, 3), ]))
# [1] "1" "3"
Кто-нибудь знает, что происходит?
Большое спасибо
Я точно не знаю, почему это происходит, но один из способов исправить это — включить аргумент rownames.force = T
внутрь as.matrix
rownames(as.matrix(test, rownames.force = T))
Прежде всего, у нас всегда есть числовой индекс для поднастройки, который не исчезнет и его не следует путать со строкой имена.
as.matrix(test)[c(1, 3), ]
# x y
# [1,] 0.1 0.1
# [2,] 1.0 0.3
ЧТО происходит при использовании rownames
, это функция dimnames
в безмятежном исходном коде base:::rownames()
,
function (x, do.NULL = TRUE, prefix = "row")
{
dn <- dimnames(x)
if (!is.null(dn[[1L]]))
dn[[1L]]
else {
nr <- NROW(x)
if (do.NULL)
NULL
else if (nr > 0L)
paste0(prefix, seq_len(nr))
else character()
}
}
что дает NULL
для dimnames(as.matrix(test))[[1]]
, но дает "1" "3"
в случае dimnames(as.matrix(test[c(1, 3), ]))[[1]]
.
Обратите внимание, что метод base:::row.names.data.frame
применяется в случае кадров данных, например. rownames(test)
.
ЧТО должно быть объяснено с ним, к счастью, вы не спросили ПОЧЕМУ, что было бы скорее основано на мнении.
@TarJae Я чувствовал такое же философское искушение, как и ты, философствовать, отвечая на этот вопрос.
Спасибо большое, теперь я лучше понимаю!
Отличие кадра данных от матрицы:
?rownames
rownames(x, do.NULL = TRUE, prefix = "row")
Важная часть do.NULL = TRUE
по умолчанию ИСТИНА: это означает:
Если do.NULL равно FALSE, вектор символов (длины NROW(x) или NCOL(x)) возвращается в любом случае,
Если замещающие версии вызываются для матрицы без каких-либо существующих имен dim, они добавят подходящие имена dim. Но такие конструкции, как
rownames(x)[3] <- "c"
может не работать, если x уже не имеет dimnames, так как это создаст значение длины 3 из значения NULL для rownames(x).
Для меня это означает (возможно, неправильное или профессиональное) применение функции rownames() к матрице, размеры строки должны быть объявлены до того, как вы получите NULL ->, потому что это настройка по умолчанию в функции rownames().
В вашем примере вы испытываете такое поведение: Здесь вы объявляете строки 1 и 3 и получаете 1 и 3
rownames(as.matrix(test[c(1, 3), ]))
[1] "1" "3"
Здесь вы ничего не объявляете и получаете NULL, потому что NULL используется по умолчанию.
rownames(as.matrix(test))
NULL
Вы можете преодолеть это, объявив перед:
rownames(test) <- 1:3
rownames(as.matrix(test))
[1] "1" "2" "3"
или вы могли бы сделать:
rownames(as.matrix(test), do.NULL = FALSE)
[1] "row1" "row2" "row3"
> rownames(as.matrix(test), do.NULL = FALSE, prefix = "")
[1] "1" "2" "3"
Аналогичный эффект с rownames.force:
имена строк.force
логическое указание, должны ли результирующие матрицы иметь символьные (а не NULL) имена строк. По умолчанию, NA, используются имена строк NULL, если фрейм данных имеет «автоматические» имена строк или для фрейма данных с нулевой строкой.
тусклые имена (matrix_test)
Вы можете включить rownames = TRUE
при подаче заявки as.matrix
> as.matrix(test, rownames = TRUE)
x y
1 0.1 0.1
2 0.1 0.2
3 1.0 0.3
Существует разница между «автоматическими» и «неавтоматическими» именами строк.
Вот мотивирующий пример:
автоматический
test <- as.data.frame(list(x = c(0.1,0.1,1), y = c(0.1,0.2,0.3)))
rownames(test)
# [1] "1" "2" "3"
rownames(as.matrix(test))
# NULL
неавтоматический
test1 <- test
rownames(test1) <- as.character(1:3)
rownames(test1)
# [1] "1" "2" "3"
rownames(as.matrix(test1))
# [1] "1" "2" "3"
Вы можете прочитать об этом, например, в ?data.frame
, в котором упоминается поведение, которое вы обнаружили в конце:
If row.names was supplied as NULL or no suitable component was found the row names are the integer sequence starting at one (and such row names are considered to be ‘automatic’, and not preserved by
as.matrix
).
Когда вы вызываете test[c(1, 3), ]
, вы неявно создаете не «автоматические» имена строк, что как бы задокументировано в ?Extract.data.frame
:
If
`[`
returns a data frame it will have unique (and non-missing) row names.
(введите `[.data.frame`
в свою консоль, если хотите углубиться в это.)
Другие уже показали, что это означает для вашего случая, см. аргумент rownames.force
в ?matrix
:
rownames.force: ... The default, NA, uses NULL rownames if the data frame has ‘automatic’ row.names or for a zero-row data frame.
большое спасибо за ваш ответ, очень полезно!
Я работал последние полчаса, пытаясь ответить на этот вопрос, и не заметил вашего ответа. Не будете ли вы так любезны просмотреть мой ответ и сказать мне, если я ошибаюсь или сбиваю с толку. Большое спасибо jay.sf