如果我想在R中保存一些方格,那很容易做到。
说,
| | 0 | 1 | 2 |
|----|------|-------|-------|
| 0 | TRUE | TRUE | FALSE |
| 1 | NA | FALSE | TRUE |
| 2 | TRUE | TRUE | FALSE |
存储为笛卡尔坐标系
m <- matrix(data = c(TRUE, TRUE, FALSE, NA, FALSE, TRUE, TRUE, TRUE, FALSE), nrow = 3, ncol = 3, byrow = FALSE)
和现有的方法和数学按预期工作:
apply(X = m, MARGIN = 2, FUN = "sum")
# [1] 2 NA 2
print(m)
# [,1] [,2] [,3]
#[1,] TRUE NA TRUE
#[2,] TRUE FALSE TRUE
#[3,] FALSE TRUE FALSE
(我知道我也可以将reshape2::melt
变成长形,但我喜欢它,因为这就是UI的样子)。
到目前为止,这么好,熟悉,直观。
现在进入六边形网格。
我从Amit Patel's marvellous/authoritative introduction to hex grids了解到,我真的应该使用立方体坐标系保存这样的网格,如上例所示,因为否则(= 2d笛卡尔坐标加偏移)线性代数运算不再起作用,并且随后会产生一般代码粗糙度。我明白了(我想)。
(有关详细信息,请再次参阅Amit Patel的精彩explainer)。
通过array()
以宽泛的形式输入这些数据似乎是完全疯狂的,因为许多细胞甚至不存在(并且已经使用了NA
)。所以我以长篇形式输入/存储,如下:
df <- rbind(c(1, 0, -1, FALSE),
c(0, 1, -1, NA),
c(1, -1, 0, TRUE),
c(0, 0, 0, TRUE),
c(-1, 1, 0, FALSE),
c(0, -1, 1, NA),
c(-1, 0, 1, TRUE))
colnames(df) <- c("y", "x", "z", "value")
df
# y x z value
#[1,] 1 0 -1 0
#[2,] 0 1 -1 NA
#[3,] 1 -1 0 1
#[4,] 0 0 0 1
#[5,] -1 1 0 0
#[6,] 0 -1 1 NA
#[7,] -1 0 1 1
这个数据框包含所有数据,但不以任何方式“知道”,x
,y
和z
是对角线坐标。
我怎么能够:
colSums()
或apply()
)print
这样的事情:(SE甚至不会正确地突出显示这个打印的十六进制网格,因此截图。)
简而言之,在R中“原生”存储这样的六边形网格的优雅/推荐/规范方式是什么?
我隐约意识到我可能会为此实现自己的S3 OO,尽管我希望这可能已经以某种形式存在。我确实发现很多软件包在连续数据上进行十六进制分箱,但它们似乎没有处理存储六角网格,或者至少没有暴露这些内部结构。
1.以宽广的形式存储它,我可以很容易地使用线性和矩阵代数
也许,http://www.redblobgames.com/grids/hexagons/#coordinates中提到的轴向坐标是这里的最佳选择。这可以提供转换为i = x和j = y的标准ij矩阵的选项,您只需要指定要放入十六进制网格未覆盖的矩阵单元格中的内容(您自己的“NA”) )。然后你可以像往常一样沿x和y维度操作,并且有一个矩形,只有空的三角形右上角和左下角三角形。 (这不是疯子,而是自然的方式。最好你必须在你的数据中为你的NA找到一个不同的解决方案。抱歉没有摆弄你的例子的代码。)
2.使用既定方法(比如colSums()或apply())
使用dplyr包你可以
df %>% as_data_frame() %>% group_by(x) %>% summarize(sum(value))
对固定的x等求和。
3.以及方便打印
我没有打印解决方案,但使用ggplot2显示标签可以解决问题
df %>% as_data_frame() %>% ggplot(aes(x=x+0.5*y, y=y, label=value)) + geom_text()
注意:这里提供的结果是您想要打印的翻版版本,但我希望您能自己找到合适的翻版。 x=x+0.5*y
在这里为您提供您所瞄准的十六进制形状。使用x=x
你只需要一个倾斜的六边形。
简而言之,在R中“原生”存储这样的六边形网格的优雅/推荐/规范方式是什么?
你已经找到了。对于计算,你使用你的df。对于存储,使用轴向效率要高一些。您可以轻松地提取z坐标。