gpt4 book ai didi

r - `names(df[1]) <- ` 和 `names(df)[1] <- ` 的区别

转载 作者:行者123 更新时间:2023-12-03 11:25:48 24 4
gpt4 key购买 nike

考虑以下:

df <- data.frame(a = 1, b = 2, c = 3)
names(df[1]) <- "d" ## First method
## a b c
##1 1 2 3

names(df)[1] <- "d" ## Second method
## d b c
##1 1 2 3

两种方法都没有返回错误,但第一种方法没有改变列名,而第二种方法却改变了。

我认为这与我仅对 df 的一个子集进行操作有关。 ,但是为什么,例如,下面的工作正常呢?
df[1] <- 2 
## a b c
##1 2 2 3

最佳答案

我认为正在发生的是替换到数据框会忽略从中提取的数据框的属性。我不是 100% 确定这一点,但以下实验似乎支持它:

df <- data.frame(a = 1:3, b = 5:7)
# a b
# 1 1 5
# 2 2 6
# 3 3 7

df2 <- data.frame(c = 10:12)
# c
# 1 10
# 2 11
# 3 12

df[1] <- df2[1] # in this case `df[1] <- df2` is equivalent

其中产生:
#    a b
# 1 10 5
# 2 11 6
# 3 12 7

注意 df 的值是如何变化的,但不是名字。基本上是替换运算符 `[<-`只替换值。这就是名称没有更新的原因。我相信这可以解释所有问题。

在场景中:
names(df[2]) <- "x"

您可以将分配视为如下(这是一个简化,有关更多详细信息,请参见文章末尾):
tmp <- df[2]
# b
# 1 5
# 2 6
# 3 7

names(tmp) <- "x"
# x
# 1 5
# 2 6
# 3 7

df[2] <- tmp # `tmp` has "x" for names, but it is ignored!
# a b
# 1 10 5
# 2 11 6
# 3 12 7

最后一步是用 `[<-` 赋值,它不尊重 RHS 的 names 属性。

但在场景中:
names(df)[2] <- "x"

您可以将分配视为(再次简化):
tmp <- names(df)
# [1] "a" "b"

tmp[2] <- "x"
# [1] "a" "x"

names(df) <- tmp
# a x
# 1 10 5
# 2 11 6
# 3 12 7

注意我们如何直接分配给 names , 而不是分配给 df忽略属性。
df[2] <- 2

之所以有效,是因为我们直接分配给值,而不是属性,所以这里没有问题。

编辑:基于@AriB.Friedman 的一些评论,这是我认为正在发生的事情的更详细的版本(注意,为了清楚起见,我省略了 S3 调度到 `[.data.frame` 等):

版本 1 names(df[2]) <- "x"翻译成:
df <- `[<-`(
df, 2,
value=`names<-`( # `names<-` here returns a re-named one column data frame
`[`(df, 2),
value="x"
) )

版本 2 names(df)[2] <- "x"翻译成:
df <- `names<-`(
df,
`[<-`(
names(df), 2, "x"
) )

此外,事实证明这是在 R Inferno 第 8.2.34 节中“记录”的(感谢@Frank):
right <- wrong <- c(a=1, b=2)
names(wrong[1]) <- 'changed'
wrong
# a b
# 1 2
names(right)[1] <- 'changed'
right
# changed b
# 1 2

关于r - `names(df[1]) <- ` 和 `names(df)[1] <- ` 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23427925/

24 4 0