Перезапись объекта в глобальной среде после использования deparse (substitute ()) при вызове функции - PullRequest
0 голосов
/ 20 декабря 2018

Это мой дебютный пост здесь.Поэтому, пожалуйста, потерпите меня, если он не соответствует высоким стандартам прозрачности более опытных участников.

У меня есть 4 объекта (представляющих 4 года) в моей глобальной среде, которые представляют собой списки, состоящие из 12 данных.кадры (по одному на каждый месяц в году).Они имеют согласованную структуру, и имена столбцов фреймов данных одинаковы.Я пытаюсь изменить эти имена столбцов фреймов данных во всех 4 списках одним махом, используя функцию, а затем перезаписать все 4 объекта в моей глобальной среде новыми объектами, которые имеют фреймы данных с новыми именами столбцов..

Это моя функция:

change.name <- function(data){
  for (i in 1:length(data)){
    names(data[[i]]) <- c("a", "b", "c", "d", "e")
  }
  assign(deparse(substitute(data)), value = data, envir = globalenv())
}

Я использую свою функцию:

change.name(my_object1)

Это работает, за исключением того, что я получаю это предупреждение:

Предупреждающее сообщение: в assign (deparse (substitute (data)), value = data, envir = globalenv ()): только первый элемент используется в качестве имени переменной

Иобъект в моей глобальной среде не перезаписывается.Я получаю новый объект с именем, подобным этому:

"список (Ян = структура (список (a = c (11, 34, 36, 49, 55, 68,"

Я понимаю, что это связано с тем, как переменная функции хранится в новой среде, которую R создает при запуске функции (или чего-то подобного).

Мой вопрос прост: какисправить это?

Ответы [ 3 ]

0 голосов
/ 20 декабря 2018

Вы можете исправить это, используя deparse(substitute(data)) перед , когда вы делаете что-либо для data:

# Let's change your function just a bit
change.name <- function(data){
    # call deparse(substutite()) *before* you do anything to data
    object_name <- deparse(substitute(data))
    for (i in 1:length(data)){
        names(data[[i]]) <- c("a", "b", "c", "d", "e")
    }
    assign(object_name, value = data, envir = globalenv())
}

# Create sample data
my_object1 <- lapply(1:12, function(x) {
    data.frame(u = 1, v = 2, x = 3, y = 4, z = 5)
})
names(my_object1) <- month.name

change.name(my_object1)
ls()
#> [1] "change.name" "my_object1"
head(my_object1, 2)
#> $January
#>   a b c d e
#> 1 1 2 3 4 5
#> 
#> $February
#>   a b c d e
#> 1 1 2 3 4 5

Создано в 2018-12-20 представьте пакет (v0.2.1)

0 голосов
/ 20 декабря 2018

Более идиоматическим (и, возможно, более безопасным) способом решения этой задачи может быть простое использование lapply и setNames:

my_object1 <- lapply(1:12, function(x) {
    data.frame(u = 1, v = 2, x = 3, y = 4, z = 5)
})
names(my_object1) <- month.name

change.name <- function(obj){
    lapply(obj,function(x) setNames(x,letters[1:5]))
}

my_object1 <- change.name(my_object1)
0 голосов
/ 20 декабря 2018

Правильно, проблема в том, как ведут себя function s.Взгляните на следующий код, он может помочь

testFun1 <- function (val) {
  a <<- val
  assign("b",a)
}
testFun2 <- function (val) {
  a <<- val
  assign("b",a, pos = 1)
}

# environment pretty much empty apart from our functions
ls()
[1] "testFun1" "testFun2"
# run
set.seed(123)
testFun1(runif(1))
# less empty
ls()
[1] "a"        "testFun1" "testFun2"
# still not quite it though
testFun2(runif(1))
# now that's better
ls()
[1] "a"        "b"        "testFun1" "testFun2"

Для получения дополнительной информации посмотрите документацию (?assign), особенно аргумент pos.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...