2016-11-29 9 views
3

Кажется, что data.frames наследует имена кодов матриц, если к ним добавлена ​​матрица функцией [. Пример:Что происходит, когда data.frame получает новые столбцы?

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"] дает «неопределенные столбцы, выбранные» -error. Два вопроса:

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

ответ

2

Присвоение целой матрицы столбцу 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», куда должны идти эти другие столбцы? Таким образом, он вставляет всю матрицу внутри столбца.

Вы можете расширить Embeded матрицы с

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.

+2

Возможно, стоит упомянуть, что присвоение 'data.frame' как' foo' для полного столбца аналогично рискованно. '<- foo [[1]]' или '<- foo [, 1]' будет хорошо защищаться. – Gregor

+0

@MrFlick, благодарю вас за ответ. Можете ли вы объяснить (или дать ссылку) тому, что встраиваемые матрицы (включая их назначение) и как R обрабатывают их? – Qaswed