Имена строк и столбцов в R
Следующие пары функций дают одинаковые результаты?
Пара 1) names()
& colnames()
Пара 2) rownames()
& row.names()
4 ответа
Как сказал Оскар Уайльд
Последовательность - последнее прибежище невообразимого.
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>
Просто чтобы немного расширить пример Дирка:
Это помогает рассматривать фрейм данных как список с векторами равной длины. Наверное, поэтому 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()
,
Так что...