考虑一下我有一个列表:
>li
$`first`
[1] "Hello"
$test
[1] 3 4 5
我试图通过以下命令更改“ first”的值:
names(li["first"]) ="sign"
但是它并没有改变变量的名称。 有人可以告诉我为什么它没有更改或此代码如何工作吗?
考虑一下,列表很大。我想知道如何在不建立索引的情况下更改变量的名称。
答案 0 :(得分:4)
您的代码不起作用,因为当您执行names(li["first"]) = "sign"
时,您正在执行的操作是:
li["first"]
-从列表中提取一个子列表。这将创建一个新列表。names(li["first"])
-获取子列表的名称,而不是原始列表的名称。names(li["first"]) = "sign"
-为子列表的一个成员分配新名称"sign"
。原始列表li
与此无关,在提取子列表的那一刻指令就丢失了它。在功能'names<-'
退出时,子列表丢失,新子列表仅在功能'names<-'
的环境中存在。 这绝对是一般性的,而不仅仅是列表。
如果要更改R对象的names
属性,则必须首先获取该属性的值,并将names
(而不是对象)作为子集。子集对象时,您正在创建一个新对象。子集属性时,您可以使对象保持完整。
如果您不知道要更改其名称的列表成员的索引号,则正确的方法是@Ronak Shah的注释。而且,如果您想同时更改多个名称,请使用%in%
而不是==
。
# Ronak Shah's comment
names(li)[names(li) == "first"] <- "sign"
names(li)
#[1] "sign" "test"
# To change 2 names use `%in%`
li2 <- list(first = "Hello", test = 3:5, second = letters[1:5])
names(li2)[names(li2) %in% c("first", "second")] <- paste("sign", 1:2, sep = "_")
names(li2)
#[1] "sign_1" "test" "sign_2"
编辑。
在用户Mikko Marttila发表评论后,我决定更准确地解释上述内容。
我认为这是对“启发式” 了解发生了什么,但与实际情况不太准确 发生。扩展
names(li["first"]) = "sign"
中的替换功能 最终等同于li <- "[<-"(li, "first", value = "names<-"(li["first"], value = "sign"))
通常,这种区别并不重要,但如果
li["first"]
有一个 行为异常'names<-'()
的类,您很讨厌 惊喜。
错误的方式。
让我们将注释中的说明分成几部分。
首先从列表li
中提取一个子列表。
sub_li <- `[`(x = li, i = "first")
sub_li
#$`first`
#[1] "Hello"
然后为该子列表的成员之一(唯一的"first"
)设置一个新名称。
sub_li <- `names<-`(x = sub_li, value = "sign")
sub_li
#$`sign`
#[1] "Hello"
然后,它将子列表sub_li
的值分配给li
的成员"first"
的成员。
li <- `[<-`(li, "first", value = sub_li)
#li
#$`first`
#[1] "Hello"
#
#$test
#[1] 3 4 5
现在,li
显然没有改变。但是确实如此,新值是"Hello"
。如果新旧值相等,这不是R的错,R照了指示去做。
为了证明发生了什么,我将更改sub_li["sign"]
的值并运行完全相同的指令。
sub_li["sign"] <- "Goodbye"
li <- `[<-`(li, "first", value = sub_li)
li
#$`first`
#[1] "Goodbye"
#
#$test
#[1] 3 4 5
看到了吗? R不是越野车。小故障是这不是程序员想要的。
正确的方法。
正确的方法要简单得多。首先创建原始列表li
。
li <- list(first = c("Hello"), test = c(3, 4, 5))
以上有效的代码(Ronak的代码)为names(li)[names(li) == "first"] <- "sign"
。忘记逻辑索引并使用索引号1
,可分为两条指令。
第一个是分配'[<-'(x, i, values)
。
stuff <- `[<-`(x = names(li), i = 1, values = "sign")
第二个是将新值分配给属性names
。
`names<-`(x = li, value = stuff)
#$`sign`
#[1] "Hello"
#
#$test
#[1] 3 4 5
R执行的单线是
li <- `names<-`(x = li, value = `[<-`(x = names(li), i = 1, values = "sign"))
li
#$`sign`
#[1] "Hello"
#
#$test
#[1] 3 4 5
就是这样。
答案 1 :(得分:0)
我想知道如何在不更改变量的情况下更改名称 索引。
您必须分配一个包含新名称的新向量。
names(li) =c("sign","test")
结果是:
> names(l)
[1] "sign" "test"
答案 2 :(得分:0)
使用您的示例:
li <- list(first = c("Hello"), test = c(3, 4, 5))
我们可以用[1]直接调用列表中的第一个元素,并用“ sign”(这是您所需要的)重命名。
names(li)[1] <- "sign"