Почему тиббл добавляет «[, 1]» к новым именам столбцов, созданным из матрицы? - PullRequest
2 голосов
/ 19 января 2020

В следующем примере я ожидал столбец с именем «rn». Почему Tibble создает столбец с именем «rn [, 1]»?

> tibble::tibble(rn = matrix(rep(1, 5), ncol = 1))
# A tibble: 5 x 1
  rn[,1]
   <dbl>
1      1
2      1
3      1
4      1
5      1

Это, кажется, происходит только при добавлении матрицы с одним столбцом.

> df <- tibble::tibble(let = letters[1:5])
> mat <- matrix(1:10, ncol = 2)
> df[, "mat1"] <- mat[, 1]
> df
# A tibble: 5 x 2
  let    mat1
  <chr> <int>
1 a         1
2 b         2
3 c         3
4 d         4
5 e         5
> mat2 <- matrix(1:5, ncol = 1)
> df[, "mat2"] <- mat2
> df
# A tibble: 5 x 3
  let    mat1 mat2[,1]
  <chr> <int>    <int>
1 a         1        1
2 b         2        2
3 c         3        3
4 d         4        4
5 e         5        5

Это не бывает при конвертации в data.frame сначала.

> df[, "mat2"] <- as.data.frame(mat2)
> df
# A tibble: 5 x 3
  let    mat1  mat2
  <chr> <int> <int>
1 a         1     1
2 b         2     2
3 c         3     3
4 d         4     4
5 e         5     5

Есть идеи? Это ошибка тиббла?

1 Ответ

3 голосов
/ 19 января 2020

Он основан на drop = TRUE в matrix и data.frame

df[, "mat1"] <- mat[, 1, drop = FALSE]
df
# A tibble: 5 x 2
#  let   mat1[,1]
#  <chr>    <int>
#1 a            1
#2 b            2
#3 c            3
#4 d            4
#5 e            5

Это будет повторять то же поведение, что и

df[, "mat2"] <- mat2

В обоих случаях мы присваивание matrix непосредственно с одним столбцом вместо пинга drop атрибутов dim при наличии одного столбца или строки (поскольку drop = TRUE по умолчанию - ?Extract)

Также поведение tibble и data.frame/matrix отличается от drop

df[, "mat1"]

Итак, когда мы делаем присвоение tibble, lhs и rhs

по-прежнему остается тибблом с одним столбцом

, тогда как если это data.frame/matrix

df[, "mat1"]

, то будет vector

df <- data.frame(let = letters[1:5])
df[["mat2"]] <- as.data.frame(mat2)
str(df)
#'data.frame':  5 obs. of  2 variables:
#$ let : Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5
#$ mat2:'data.frame':   5 obs. of  1 variable:
# ..$ V1: int  1 2 3 4 5

Сейчас мы проверяем то же самое в tibble

df <- tibble(let = letters[1:5])
df[["mat2"]] <- as.data.frame(mat2)
str(df)
#tibble [5 × 2] (S3: tbl_df/tbl/data.frame)
#$ let : chr [1:5] "a" "b" "c" "d" ...
# $ mat2:'data.frame':  5 obs. of  1 variable:
#  ..$ V1: int [1:5] 1 2 3 4 5

В обоих случаях он возвращает data.frame столбец 'V1', но в методе печати для tibble он возвращает

df
# A tibble: 5 x 2
#  let   mat2$V1
#  <chr>   <int>
#1 a           1
#2 b           2
#3 c           3
#4 d           4
#5 e           5

в data.frame это будет

df
#  let V1
#1   a  1
#2   b  2
#3   c  3
#4   d  4
#5   e  5

Если мы не проверим str в обоих случаях, это будет иметь некоторые последствия при выполнении некоторых преобразований

...