Skip to content

R - 数组

在 R 中,数组 (array) 是一种数据结构,用于存储超过两个维度的数据。它本质上是向量的多维扩展,这意味着数组中的所有元素都必须是相同的数据类型。

例如,一个维度为 (行=2, 列=3, 深度=4) 的三维数组可以被看作是 4 个矩阵,每个矩阵有 2 行 3 列。虽然数组在科学计算或图像处理等特定应用中功能强大,但与针对二维表格数据优化的数据框 (data frames) 和 tibble 相比,它们在一般数据分析中不那么常见。

你可以使用 array() 函数创建数组,该函数接受一个数据向量和一个指定维度的 dim 参数。

# 创建一个数据向量。其长度应为维度乘积(2*3*2=12)。
# 我们将为两个 2x3 矩阵创建数据。
matrix_data_1 <- c(5, 9, 3, 10, 11, 12)
matrix_data_2 <- c(13, 14, 15, 6, 0, 1)
all_data <- c(matrix_data_1, matrix_data_2)
# 创建一个具有 2 行、3 列和 2 个“层”(矩阵)的数组
result_array <- array(all_data, dim = c(2, 3, 2))
print(result_array)

这会产生以下输出。请注意 R 如何按列、然后按行、然后按下一维度填充数组。

, , 1
[,1] [,2] [,3]
[1,] 5 3 11
[2,] 9 10 12
, , 2
[,1] [,2] [,3]
[1,] 13 15 0
[2,] 14 6 1

为了清晰起见,最佳实践是使用 dimnames 参数命名维度,该参数接受一个字符向量列表。

# 为每个维度定义名称
row_names <- c("ROW1", "ROW2")
col_names <- c("COL1", "COL2", "COL3")
matrix_names <- c("Sensor_A", "Sensor_B")
# 使用命名维度重新创建数组
named_array <- array(all_data, dim = c(2, 3, 2), dimnames = list(row_names, col_names, matrix_names))
print(named_array)

输出现在更具可读性:

, , Sensor_A
COL1 COL2 COL3
ROW1 5 3 11
ROW2 9 10 12
, , Sensor_B
COL1 COL2 COL3
ROW1 13 15 0
ROW2 14 6 1

你可以使用方括号 [行, 列, 层, ...] 访问元素。留空维度表示选择该维度的所有元素。

# 获取第二个矩阵('Sensor_B')的第1行、第3列的元素
print(named_array[1, 3, 2])
# 获取第一个矩阵('Sensor_A')的整个第二行
print(named_array[2, , 1])
# 获取整个第二个矩阵('Sensor_B')
print(named_array[, , 2])
# 将两个矩阵逐元素相加
matrix_sum <- named_array[, , 1] + named_array[, , 2]
print(matrix_sum)

这些操作的输出:

[1] 0
COL1 COL2 COL3
9 10 12
COL1 COL2 COL3
ROW1 13 15 0
ROW2 14 6 1
COL1 COL2 COL3
ROW1 18 18 11
ROW2 23 16 13

使用 apply() 对数组元素进行计算

Section titled “使用 apply() 对数组元素进行计算”

apply() 函数是一个强大的工具,用于在数组的边距(维度)上应用函数。

语法:apply(X, MARGIN, FUN)

  • X:数组。
  • MARGIN:应用函数的维度。1 表示行,2 表示列,c(1, 2) 表示行和列等。
  • FUN:要应用的函数(例如,sum、mean)。
# 计算每一行的总和,跨越所有矩阵
# 结果是 ROW1 的总和和 ROW2 的总和
row_sums <- apply(named_array, 1, sum)
print(row_sums)
# 计算每一列的平均值,跨越所有矩阵
# 结果是 COL1、COL2 和 COL3 的平均值
col_means <- apply(named_array, 2, mean)
print(col_means)

输出:

ROW1 ROW2
47 52
COL1 COL2 COL3
10.25 8.50 6.00

现代视角:何时使用数组与整洁数据 (Tidy Data)

Section titled “现代视角:何时使用数组与整洁数据 (Tidy Data)”

虽然数组对于多维数据是必要的,但大多数数据分析任务都受益于整洁数据 (tidy data) 格式,其中:

  1. 每个变量构成一列。
  2. 每个观测值构成一行。
  3. 每种观测单元构成一个表。

数组可以转换为整洁的 tibble(一种现代数据框)。这使得它与 dplyr 和 ggplot2 等工具兼容。

# install.packages("tibble") # 运行一次
library(tibble)
library(dplyr)
# 将数组转换为整洁的 tibble
tidy_array <- as_tibble(as.data.frame.table(named_array))
# 重新命名列以提高清晰度
tidy_array <- tidy_array %>%
rename(Row = Var1, Column = Var2, Sensor = Var3, Value = Freq)
print(tidy_array)
# 现在,我们可以使用 dplyr 执行与 apply() 相同的行求和计算
summarized_data <- tidy_array %>%
group_by(Row) %>%
summarize(TotalValue = sum(Value))
print(summarized_data)

指导原则:当 N 维结构和位置访问至关重要时(例如,矩阵代数、图像分析),请使用数组。对于大多数统计分析和可视化,请首先将数据转换为整洁格式。