Что происходит, когда в data.frame появляются новые столбцы?

Похоже, что data.frames наследуют имена столбцов матриц, если матрица добавляется к ним функцией [. Пример:

blob <- matrix(11:20, ncol = 1, dimnames = list(NULL, "BLOB"))
foo <- data.frame(FOO = 201:210)

dat <- data.frame(id = 1:10)

dat[, "new1"] <- blob 
dat[, "new2"] <- foo

Если я сейчас посмотрю на dat, он покажет мне

id BLOB new2
1   11  201
2   12  202
3   13  203
...

Таким образом, отображается не ожидаемое "new1", а "BLOB"; даже если colnames(dat) это "id", "new1" и "new2". Кроме того, "BLOB" нигде не находится в attributes(dat), а dat[, "BLOB"] выдает ошибку "выбраны неопределенные столбцы". Два вопроса:

  1. почему dat показывает "BLOB", а не "new1" в данном случае?
  2. Как изменить dat так, чтобы вместо "BLOB" отображалось "new1"?

person Qaswed    schedule 29.11.2016    source источник


Ответы (1)


Присвоение всей матрицы столбцу data.frame создает очень странный объект. Если вы посмотрите на структуру dat, вы увидите

'data.frame':   10 obs. of  3 variables:
 $ id  : int  1 2 3 4 5 6 7 8 9 10
 $ new1: int [1:10, 1] 11 12 13 14 15 16 17 18 19 20
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr "BLOB"
 $ new2: int  201 202 203 204 205 206 207 208 209 210

Итак, вы добавили столбец, который по-прежнему является матрицей. И вы можете видеть, что встроенная матрица сохранила имя столбца «BLOB». Было бы безопаснее просто присвоить столбец матрицы столбцу data.frame с помощью

dat[, "new1"] <- blob[,1] 

Это происходит потому, что blob может иметь более одного столбца. Если вы назначите его только «new1», куда должны идти эти другие столбцы? Таким образом, вся матрица встраивается в столбец.

Вы можете расширить встроенные матрицы с помощью

do.call("cbind.data.frame", dat)

который сохранит имя столбца «BLOB», но теперь это будет «обычный» data.frame, поэтому «BLOB» будет указан в colnames()

Когда R печатает data.frame с внедренной матрицей, обычно он добавляет префикс имени столбца data.frame перед именами столбцов матрицы, но когда есть только один столбец, он использует только имя столбца матрицы (что, по общему признанию, может сбивать с толку). Наблюдать:

mm<-matrix(1:9+10, nrow=3, dimnames=list(NULL, c("m1","m2","m3")))
data.frame(a=1:3, b = mm, c=letters[1:3])
#   a b.m1 b.m2 b.m3 c
# 1 1   11   14   17 a
# 2 2   12   15   18 b
# 3 3   13   16   19 c
data.frame(a=1:3, b = mm[,1, drop=FALSE], c=letters[1:3])
#   a m1 c
# 1 1 11 a
# 2 2 12 b
# 3 3 13 c

Короче говоря: не помещайте матрицу в data.frame.

person MrFlick    schedule 29.11.2016
comment
Вероятно, стоит упомянуть, что назначение data.frame как foo для полного столбца также рискованно. <- foo[[1]] или <- foo[, 1] было бы неплохо обороняться. - person Gregor Thomas; 29.11.2016
comment
@MrFlick, спасибо за ответ. Можете ли вы объяснить (или дать ссылку), что такое встроенные матрицы (включая их назначение) и как R с ними справляется? - person Qaswed; 30.11.2016