网格单元向量中的元素替换
element replacement in grid unit vector
我已经被这个问题困扰过好几次了,所以这里有一个编造的问题,供其他可能偶然发现同样问题的人使用。
考虑这个网格单位向量,
a = unit(1:3, c("cm", "in", "npc"))
我想用新值替换一些元素。自然的方法是,
a[1] = unit(2,"pt")
a
# [1] 2cm 2in 3npc
出了点问题:只更改了数值,没有更改单位。为什么?怎么办?
编辑: 正如下面的一个答案所指出的,这些单位只是具有属性的数字向量。然而,他们的后代 unit.arithmetic
和 unit.list
也应该被认为是完全通用的解决方案(例如用于调整 ggplot 对象的面板大小)。考虑这个单位向量,
(b = a + unit(1, "npc"))
# [1] 1cm+1npc 2in+1npc 3npc+1npc
# [1] "unit.arithmetic" "unit"
现在替换特定元素更加棘手,因为它们不再是原子的。
看起来 a
只是一个附加了一些属性的原子向量。因此,当您使用 a[1] = unit(2,"pt")
时,新的 unit
函数会创建另一个长度为 1 的原子向量来替换 a[1]
的值。属性保持不变。
所以,这样的事情似乎有效:
a[1] <- 2
attr(a, 'unit')[1] <- 'pt'
> a
[1] 2pt 2in 3npc
在与 Paul Murrell 讨论之后(有趣的是,重新发明了我想要 的东西),问题在于缺少网格单元的 [<-
方法。长期的解决方法是实施这些方法,但这并非微不足道,因为网格单元带有 unit.arithmetic 和 unit.list 等兄弟单元,并且它们的交互可能变得难以理解。
更简单、面向用户的修复方法是将此类单位向量转换为 unit.list 对象,这将更像常规 R 列表一样继承访问器方法。可以使用未导出的函数 grid:::unit.list()
.
完成对 unit.list 对象的提升
a = unit(1:3, c("cm", "in", "npc"))
b = grid:::unit.list(a)
is.list(b) # check that indeed this is a list object, thanks @Josh O'Brien
# [1] TRUE
# so now we can use standard list methods
b[[1]] = unit(2,"pt")
b
#[1] 2pt 2in 3npc
我已经被这个问题困扰过好几次了,所以这里有一个编造的问题,供其他可能偶然发现同样问题的人使用。
考虑这个网格单位向量,
a = unit(1:3, c("cm", "in", "npc"))
我想用新值替换一些元素。自然的方法是,
a[1] = unit(2,"pt")
a
# [1] 2cm 2in 3npc
出了点问题:只更改了数值,没有更改单位。为什么?怎么办?
编辑: 正如下面的一个答案所指出的,这些单位只是具有属性的数字向量。然而,他们的后代 unit.arithmetic
和 unit.list
也应该被认为是完全通用的解决方案(例如用于调整 ggplot 对象的面板大小)。考虑这个单位向量,
(b = a + unit(1, "npc"))
# [1] 1cm+1npc 2in+1npc 3npc+1npc
# [1] "unit.arithmetic" "unit"
现在替换特定元素更加棘手,因为它们不再是原子的。
看起来 a
只是一个附加了一些属性的原子向量。因此,当您使用 a[1] = unit(2,"pt")
时,新的 unit
函数会创建另一个长度为 1 的原子向量来替换 a[1]
的值。属性保持不变。
所以,这样的事情似乎有效:
a[1] <- 2
attr(a, 'unit')[1] <- 'pt'
> a
[1] 2pt 2in 3npc
在与 Paul Murrell 讨论之后(有趣的是,重新发明了我想要 [<-
方法。长期的解决方法是实施这些方法,但这并非微不足道,因为网格单元带有 unit.arithmetic 和 unit.list 等兄弟单元,并且它们的交互可能变得难以理解。
更简单、面向用户的修复方法是将此类单位向量转换为 unit.list 对象,这将更像常规 R 列表一样继承访问器方法。可以使用未导出的函数 grid:::unit.list()
.
a = unit(1:3, c("cm", "in", "npc"))
b = grid:::unit.list(a)
is.list(b) # check that indeed this is a list object, thanks @Josh O'Brien
# [1] TRUE
# so now we can use standard list methods
b[[1]] = unit(2,"pt")
b
#[1] 2pt 2in 3npc