Сегодня у меня появился странный результат.
Чтобы воспроизвести его, рассмотрите следующие фреймы данных:
x <- data.frame(x=1:3, y=11:13)
y <- x[1:3, 1:2]
Они должны быть и на самом деле идентичны:
identical(x,y)
# [1] TRUE
Применение t()
к indentical объектам должно давать тот же результат, но:
identical(t(x),t(y))
# [1] FALSE
Разница заключается в именах столбцов:
colnames(t(x))
# NULL
colnames(t(y))
# [1] "1" "2" "3"
Учитывая это, если вы хотите стек y
по столбцам, вы получите то, что ожидаете:
stack(as.data.frame(t(y)))
# values ind
# 1 1 1
# 2 11 1
# 3 2 2
# 4 12 2
# 5 3 3
# 6 13 3
а
stack(as.data.frame(t(x)))
# values ind
# 1 1 V1
# 2 11 V1
# 3 2 V2
# 4 12 V2
# 5 3 V3
# 6 13 V3
В последнем случае as.data.frame()
не находит исходные имена столбцов и автоматически генерирует их.
Претендент находится в as.matrix()
, называемом t()
:
rownames(as.matrix(x))
# NULL
rownames(as.matrix(y))
# [1] "1" "2" "3"
Обходным путем является установка rownames.force
:
rownames(as.matrix(x, rownames.force=TRUE))
# [1] "1" "2" "3"
rownames(as.matrix(y, rownames.force=TRUE))
# [1] "1" "2" "3"
identical(t(as.matrix(x, rownames.force=TRUE)),
t(as.matrix(y, rownames.force=TRUE)))
# [1] TRUE
(и переписать stack(...)
вызов соответственно.)
Мои вопросы:
-
Почему
as.matrix()
обрабатывает по-разномуx
иy
и -
как вы можете рассказать о различии между ними?
Обратите внимание, что другие функции информации не обнаруживают различий между x, y
:
identical(attributes(x), attributes(y))
# [1] TRUE
identical(str(x), str(y))
# ...
#[1] TRUE
Комментарии к решениям
Конрад Рудольф дает краткое, но эффективное объяснение поведения, описанного выше (см. также mt1022 для более подробной информации).
Короче Конрад показывает, что:
a) x
и y
являются внутренне разными;
b) "identical
тоже слишком слабо по умолчанию", чтобы уловить эту внутреннюю разницу.
Теперь, если вы берете подмножество T
для набора S
, которое имеет все элементы S
, то S
и T
являются точно такими же объектами. Итак, если вы берете фрейм данных y
, который имеет все строки и столбцы x
, то x
и y
должны быть точно такими же объектами. К сожалению x \neq y
!
Это поведение не только противоречит интуиции, но и запутывается, то есть разница не очевидна, но внутренняя и даже функция по умолчанию identical
не могут ее видеть.
Другим естественным принципом является то, что перенос двух идентичных (матричноподобных) объектов создает одинаковые объекты. Опять же, это нарушается тем, что перед транспонированием identical
является "слишком слабым"; после транспонирования по умолчанию identical
достаточно, чтобы увидеть разницу.
ИМХО такое поведение (даже если это не ошибка) является неправильным поведением для научного языка, такого как R.
Надеюсь, этот пост привлечет некоторое внимание, и команда R рассмотрит его пересмотр.