功能范围 - 重命名列

问题描述 投票:0回答:2

通常,如果我试图重命名R中的数据帧的列,我会使用

data(iris)
colnames(iris)[colnames(iris) == "Petal.Length"] <- "petal_height"

所以我想如果我把它变成一个简单的函数,我会看到发生了什么

renamer <- function(data, oldname, newname) {
  colnames(data)[colnames(data) == oldname] <- newname
}

但是,虽然该函数运行时没有错误,但似乎没有对数据帧进行任何明显的更改。

renamer(iris, "Petal.Length", "petal_height")

虽然这只是将newname分配给虹膜的值

iris <- renamer(iris, "Petal.Length", "petal_height")

是否有人能够解释为什么这种行为正在发生?

请注意,我实际上并不需要重命名功能。我只是想了解为什么这不起作用,因为我认为它会。

r
2个回答
1
投票

平原:

renamer(iris, "Petal.Length", "petal_height")

不会更改iris对象,因为R在函数内部使用局部范围。更改不会“泄漏”到调用上下文(没有做特殊的技巧。不要这样做)。

当你这样做时:

iris <- renamer(iris, "Petal.Length", "petal_height")

它不起作用,因为函数的返回值是return(...)函数调用中的参数或函数的最后一个参数。所以:

renamer <- function(data, oldname, newname) {
  colnames(data)[colnames(data) == oldname] <- newname
  return(data)
}

应该与iris = renamer(iris,....)合作

当您的功能完成时:

colnames(data)[colnames(data) == oldname] <- newname

R在该函数中做的最后一件事是评估newname,所以它返回了"petal_height"


-1
投票

使用package::dplyr

iris %>% rename_all(function(x)tolower(gsub('\\.', '_', x, perl = TRUE))) %>% colnames()
[1] "sepal_length" "sepal_width"  "petal_length" "petal_width"  "species" 

edit for the comment that this isn't representative of the column names in iris....

> data("iris")
> colnames(iris)
[1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species"  

> iris %>% rename_all(function(x)sprintf('[OLD]%s | [NEW]%s', x, tolower(gsub('\\.', '_', x, perl = TRUE)))) %>% 
head(1) %>% str

'data.frame':   1 obs. of  5 variables:
 $ [OLD]Sepal.Length | [NEW]sepal_length: num 5.1
 $ [OLD]Sepal.Width | [NEW]sepal_width  : num 3.5
 $ [OLD]Petal.Length | [NEW]petal_length: num 1.4
 $ [OLD]Petal.Width | [NEW]petal_width  : num 0.2
 $ [OLD]Species | [NEW]species          : Factor w/ 3 levels
© www.soinside.com 2019 - 2024. All rights reserved.