Выполняют ли следующие пары функций одинаковые результаты?
Пара 1) names()
и colnames()
Пара 2) rownames()
и row.names()
Выполняют ли следующие пары функций одинаковые результаты?
Пара 1) names()
и colnames()
Пара 2) rownames()
и row.names()
Как сказал Оскар Уайльд
Консистенция - последнее убежище прозаический.
R - скорее развитый, чем разработанный язык, поэтому все происходит. names()
и colnames()
работают с data.frame
, но names()
не работает над матрицей:
R> DF <- data.frame(foo=1:3, bar=LETTERS[1:3])
R> names(DF)
[1] "foo" "bar"
R> colnames(DF)
[1] "foo" "bar"
R> M <- matrix(1:9, ncol=3, dimnames=list(1:3, c("alpha","beta","gamma")))
R> names(M)
NULL
R> colnames(M)
[1] "alpha" "beta" "gamma"
R>
Чтобы немного рассказать о примере Dirk:
Это помогает думать о кадре данных как о списке с векторами равной длины. Вероятно, поэтому names
работает с фреймом данных, но не с матрицей.
Другая полезная функция - dimnames
, которая возвращает имена для каждого измерения. Вы заметите, что функция rownames
фактически возвращает первый элемент из dimnames
.
Относительно rownames
и row.names
: я не могу сказать разницы, хотя rownames
использует dimnames
, а row.names
был написан вне R. Они оба, похоже, работают с массивами с более высокой размерностью:
>a <- array(1:5, 1:4)
> a[1,,,]
> rownames(a) <- "a"
> row.names(a)
[1] "a"
> a
, , 1, 1
[,1] [,2]
a 1 2
> dimnames(a)
[[1]]
[1] "a"
[[2]]
NULL
[[3]]
NULL
[[4]]
NULL
Я думаю, что использование colnames
и rownames
имеет наибольший смысл; вот почему.
Использование names
имеет несколько недостатков. Вы должны помнить, что это означает "имена столбцов", и он работает только с фреймом данных, поэтому вам нужно будет называть colnames
всякий раз, когда вы используете матрицы. Вызывая colnames
, вам нужно запомнить только одну функцию. Наконец, если вы посмотрите на код для colnames
, вы увидите, что он вызывает names
в случае кадра данных в любом случае, поэтому вывод идентичен.
rownames
и row.names
возвращают одинаковые значения для фрейма данных и матриц; единственное отличие, которое я заметил, это то, что там, где нет имен, rownames
будет печатать "NULL" (как и colnames
), но row.names
возвращает его невидимо. Поскольку между двумя функциями не так много выбора, rownames
выигрывает на основе эстетики, так как он лучше сочетается с colnames
. (Кроме того, для ленивого программиста вы сохраняете характер ввода.)
И еще одно расширение:
# create dummy matrix
set.seed(10)
m <- matrix(round(runif(25, 1, 5)), 5)
d <- as.data.frame(m)
Если вы хотите назначить новые имена столбцов, вы можете сделать следующее на data.frame
:
# an identical effect can be achieved with colnames()
names(d) <- LETTERS[1:5]
> d
A B C D E
1 3 2 4 3 4
2 2 2 3 1 3
3 3 2 1 2 4
4 4 3 3 3 2
5 1 3 2 4 3
Если вы, однако, запустили предыдущую команду на matrix
, вы все испортите:
names(m) <- LETTERS[1:5]
> m
[,1] [,2] [,3] [,4] [,5]
[1,] 3 2 4 3 4
[2,] 2 2 3 1 3
[3,] 3 2 1 2 4
[4,] 4 3 3 3 2
[5,] 1 3 2 4 3
attr(,"names")
[1] "A" "B" "C" "D" "E" NA NA NA NA NA NA NA NA NA NA NA NA NA NA
[20] NA NA NA NA NA NA
Поскольку матрицу можно рассматривать как двумерный вектор, вы присваиваете имена только первым пяти значениям (вы не хотите этого делать, не так ли?). В этом случае вы должны придерживаться colnames()
.
Итак, там...