为了解决第一个问题,我们首先创建一个向量和一个一维数组:
(vector <- 1:10)
#> [1] 1 2 3 4 5 6 7 8 9 10
(arr_1d <- array(1:10, dim = 10))
#> [1] 1 2 3 4 5 6 7 8 9 10
如果我们给对象一些名字,我们可以看到区别
Ripley 通过查看属性暗示了这一点:
names(vector) <- letters[1:10]
names(arr_1d) <- letters[1:10]
attributes(vector)
#> $names
#> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
attributes(arr_1d)
#> $dim
#> [1] 10
#>
#> $dimnames
#> $dimnames[[1]]
#> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
也就是说,一维数组实际上没有names 属性,
而是一个dimnames 属性(它是一个列表,而不是一个向量),
names() 实际访问的第一个元素。
这在?names 的“注意”部分中有介绍:
对于向量,名称是具有限制的属性之一
可能的值。对于配对列表,名称是标签和
与字符向量相互转换。
对于一维数组,names 属性确实是
暗名[[1]]。
这里我们还看到缺少dim
向量的属性。 (A related SO answer 也涵盖了数组和向量之间的差异。)
附加属性及其存储方式意味着
一维数组总是比它们的等效向量占用更多的内存:
# devtools::install_github("r-lib/lobstr")
lobstr::obj_size(vector)
#> 848 B
lobstr::obj_size(arr_1d)
#> 1,056 B
但是,这是我能想到的唯一原因
将希望对向量和一维数组有单独的类型。我认为这确实是约根森的问题
问,即 为什么 有一个单独的 vector 类型而没有 dim
属性;而且我认为里普利并没有真正解决这个问题。
我很想听听其他理由。
至于第 2 点),当您使用 : 创建矢量时
始终是整数:
vector <- 1:10
typeof(vector)
#> [1] "integer"
具有相同值的双精度将打印相同:
double <- as.numeric(vector)
typeof(double)
#> [1] "double"
double
#> [1] 1 2 3 4 5 6 7 8 9 10
但整数和双精度不是一回事:
identical(vector, double)
#> [1] FALSE
R 中的整数和双精度数之间的区别是微妙的,主要是
一是整数在内存中占用的空间更少。
lobstr::obj_size(vector)
#> 88 B
lobstr::obj_size(double)
#> 168 B
请参阅this answer 以更全面地了解整数和双精度之间的差异。
由reprex package (v0.2.0.9000) 于 2018 年 7 月 9 日创建。