如何编辑R中的多人对象

时间:2014-06-11 03:43:01

标签: r

我发现R person对象的以下行为非常意外:

让我们创建一个多人对象:

a = c(person("Huck", "Finn"), person("Tom", "Sawyer"))

想象一下,我们想要更新对象中一个人的给定名称:

a[[1]]$given <- 'Huckleberry'

然后,如果我们检查我们的对象,我惊讶地发现:

> a
[1] "  <> [] ()" "Tom Sawyer"

哈克贝利·芬恩去哪儿了?! (请注意,如果我们只用一个人对象来尝试它,它就可以正常工作。)为什么会发生这种情况?

我们如何才能完成上述工作,以便我们能够更正逻辑地纠正名字?

1 个答案:

答案 0 :(得分:3)

您想要的语法是

a <-  c(person("Huck", "Finn"), person("Tom", "Sawyer"))
a[1]$given<-"Huckleberry"
a

#[1] "Huckleberry Finn" "Tom Sawyer"

一群人仍然是一个&#34;并且它拥有自己的特殊索引函数[.person和concat函数c.person,因此它可能具有与您期望的不同的行为。问题是[[ ]]弄乱了潜在的隐藏列表。

实际上,它很有趣,因为他们已经重载了person的几乎所有索引方法,但没有重载[<-[[<-的那些索引方法真的很重要导致错误的是什么因为到这里,我们是相同的

`$<-`(`[`(a,1), "given", "Huckleberry") #works
`$<-`(`[[`(a,1), "given", "Huckleberry") #works

但是当我们到达

`[<-`(a, 1, `$<-`(`[`(a,1), "given", "Huckleberry")) #works
`[[<-`(a, 1, `$<-`(`[[`(a,1), "given", "Huckleberry")) #no work

我们看到了不同之处。在检索期间发生的特殊包装/展开不会在分配期间发生。

所以,正在发生的事情是一个&#34;人&#34;始终是列表的列表。外部列表包含所有人,内部列表包含数据。你可以想到像这样的数据

x<-list(
    list(name="a"),list(name="b")
)

y<-list(
    list(name="c")
)

其中x是两个人的集合,y是&#34;单个&#34;人。当你这样做

x[1]<-y
x

你最终得到了

list(
    list(name="c"),list(name="b")
)

因为您要使用列表替换列表,列表是[索引与列表一起使用的方式。但是,如果您尝试使用列表列表替换[[1]]处的元素,则该列表将嵌套。例如

x[[1]]<-y
x

变为

x<-list(
    list(list(name="c")),list(name="b")
)

当它在第一个位置打印人时,额外的嵌套水平是令人困惑的R。第一个人在第二级没有任何命名元素,所以当它打印时,它将返回

emptyp <- structure(list(structure(list(), class="person")), class="person")
utils:::format.person(emptyp)
#  "  <> [] ()"

给出的是它试图放置姓名,电子邮件地址,角色和评论的符号。