`name(df [1])< - `和`names(df)[1]之间的区别< - [英] Difference between `names(df[1]) <- ` and `names(df)[1] <- `

查看:160
本文介绍了`name(df [1])< - `和`names(df)[1]之间的区别< - 的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下内容:

  df<  -  data.frame(a = 1,b = 2,c = 3 )
名称(df [1])< - d##第一种方法
## abc
## 1 1 2 3

名称(df )[1]< - d##第二种方法
## dbc
## 1 1 2 3

两个方法都没有返回错误,但是第一个没有更改列名称,而第二个方法没有。



我以为这与我仅在 df 的一个子集上进行操作有关,但为什么例如以下的工作呢?

  df [1]<  -  2 
## abc
## 1 2 2 3


解决方案

我认为发生的是将替换成数据帧忽略属性的数据框架。我不是100%肯定的,但以下实验似乎支持:

  df<  -  data.frame (a = 1:3,b = 5:7)
#ab
#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]#在这种情况下`df [1]< - df2`是等价的

哪些产生:

 #ab 
#1 10 5
#2 11 6
#3 12 7

请注意, df ,但不是名字。基本上,替换运算符`[< -` 仅替换值。这就是为什么这个名字没有更新。我相信这解释了所有的问题。



在这种情况下:

 名称(df [2])<  - x

您可以将作业视为以下(这是一个简化,详见后篇):

  tmp < -  df [2] 
#b
#1 5
#2 6
#3 7

名称(tmp)< - x
#x
#1 5
#2 6
#3 7

df [2]< - tmp#`tmp'有x的名字,忽略了
#ab
#1 10 5
#2 11 6
#3 12 7

最后一步是使用`[< -` ,不遵守RHS的名称属性的作业。



但是在这种情况下:

  names(df)[2 ]<  - x

你可以将作业看作(再一次简化):

  tmp<  - 名称(df)
#[1]ab

tmp [2]< - x
#[1]ax

名称(df)< - tmp
#ax
#1 10 5
#2 11 6
#3 12 7



注意我们如何直接分配给名称,而不是分配给忽略属性的 df

  df [2]<  -  2 

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





$ b $编辑:根据一些评论om @ AriB.Friedman,这里是一个更精细的版本,我认为是这样(注意我省略了S3发送到`[.data.frame` 等等,为了清楚起见):



版本1 名称(df [2])< - x转换为:

  df<  - `[< -`(
df,2,
value =`names <-`(#`names< -`这里返回一个重新命名的一列数据框
`[`(df,2),
value =x

版本2 名称(df)[2]< - x转换为:

  df<  - `names< -`(
df,
`[< -`(
names(df),2,x
))






另外,在R Inferno Section 8.2.34(Thanks @Frank)中证明了这一点是记录的:

  right<  -  wrong<  -  c(a = 1,b = 2)
名称(错误[1])< - '更改'
错误
#ab
#1 2
名称(右)[1]< - '更改'
right
# d b
#1 2


Consider the following:

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

Both methods didn't return an error, but the first didn't change the column name, while the second did.

I thought it has something to do with the fact that I'm operating only on a subset of df, but why, for example, the following works fine then?

df[1] <- 2 
##  a b c
##1 2 2 3

解决方案

What I think is happening is that replacement into a data frame ignores the attributes of the data frame that is drawn from. I am not 100% sure of this, but the following experiments appear to back it up:

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

Which produces:

#    a b
# 1 10 5
# 2 11 6
# 3 12 7

Notice how the values changed for df, but not the names. Basically the replacement operator `[<-` only replaces the values. This is why the name was not updated. I believe this explains all the issues.

In the scenario:

names(df[2]) <- "x"

You can think of the assignment as follows (this is a simplification, see end of post for more detail):

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

The last step of which is an assignment with `[<-`, which doesn't respect the names attribute of the RHS.

But in the scenario:

names(df)[2] <- "x"

you can think of the assignment as (again, a simplification):

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

Notice how we directly assign to names, instead of assigning to df which ignores attributes.

df[2] <- 2

works because we are assigning directly to the values, not the attributes, so there are no problems here.


EDIT: based on some commentary from @AriB.Friedman, here is a more elaborate version of what I think is going on (note I'm omitting the S3 dispatch to `[.data.frame`, etc., for clarity):

Version 1 names(df[2]) <- "x" translates to:

df <- `[<-`(
  df, 2, 
  value=`names<-`(   # `names<-` here returns a re-named one column data frame
    `[`(df, 2),       
    value="x"
) ) 

Version 2 names(df)[2] <- "x" translates to:

df <- `names<-`(
  df,
  `[<-`(
     names(df), 2, "x"
) )


Also, turns out this is "documented" in R Inferno Section 8.2.34 (Thanks @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

这篇关于`name(df [1])&lt; - `和`names(df)[1]之间的区别&lt; - 的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆