Изменение подмножества имен столбцов в списке фреймов данных в R - PullRequest
0 голосов
/ 08 июня 2018

Этот вопрос является расширением Изменение имен столбцов в списке фреймов данных в R .

В этой публикации рассматриваются изменяющиеся имена всех столбцов данных..frame.

Но как изменить имена только выбранного числа столбцов?

Пример:

Я хочу изменить имятолько в первом столбце в каждом data.frame в моем списке:

dat <- data.frame(Foo = 1:5,Bar = 1:5)
lst <- list(dat,dat)

print(lst)

[[1]]
  Foo Bar
1   1   1
2   2   2
3   3   3
4   4   4
5   5   5

[[2]]
  Foo Bar
1   1   1
2   2   2
3   3   3
4   4   4
5   5   5

(Failed) Попытки:

lapply(1:2, function(x) names(lst[[x]])[names(lst[[x]]) == 'Foo'] <- 'New')
lapply(1:2, function(x) names(lst[[x]])[names(lst[[x]]) == 'Foo'])  <- rep('New',2)
lapply(1:2, function(x) setNames(lst[[x]][names(lst[[x]]) == 'Foo'],'New'))

Ответы [ 6 ]

0 голосов
/ 11 июня 2018

Использование tidyverse:

library(tidyverse)
map(lst,rename_at,"Foo",~"New")
# [[1]]
# New Bar
# 1   1   1
# 2   2   2
# 3   3   3
# 4   4   4
# 5   5   5
# 
# [[2]]
# New Bar
# 1   1   1
# 2   2   2
# 3   3   3
# 4   4   4
# 5   5   5

Использование data.table:

library(data.table)
lst2 <- copy(lst)
lapply(lst2,setnames,"Foo","New")

# [[1]]
# New Bar
# 1   1   1
# 2   2   2
# 3   3   3
# 4   4   4
# 5   5   5
# 
# [[2]]
# New Bar
# 1   1   1
# 2   2   2
# 3   3   3
# 4   4   4
# 5   5   5

Здесь изменения делаются по ссылке, поэтому мы сначала делаем копию.

0 голосов
/ 08 июня 2018

Примечание без назначения, оно не меняет исходный объект.

lst <- purrr::map(lst, ~setNames(.x, c('new', names(.x)[-1])))

0 голосов
/ 08 июня 2018

Мое решение более сложное, чем другие, но оно здесь.

Основное отличие состоит в том, что вместо == используется grep (с аргументом ignore.case = TRUE).

lapply(lst, function(DF) {
  inx <- grep("^foo$", names(DF), ignore.case = TRUE)
  names(DF)[inx] <- "New"
  DF
})
#[[1]]
#  New Bar
#1   1   1
#2   2   2
#3   3   3
#4   4   4
#5   5   5
#
#[[2]]
#  New Bar
#1   1   1
#2   2   2
#3   3   3
#4   4   4
#5   5   5
0 голосов
/ 08 июня 2018

Вот способ изменить имя столбца по индексу столбца.

lapply(lst, function(x, pos = 1, newname = "New"){
  # x: data frame, pos: column index, newname: new name of the column
  column <- names(x)
  column[pos] <- newname
  names(x) <- column
  return(x)
})
# [[1]]
#   New Bar
# 1   1   1
# 2   2   2
# 3   3   3
# 4   4   4
# 5   5   5
# 
# [[2]]
#   New Bar
# 1   1   1
# 2   2   2
# 3   3   3
# 4   4   4
# 5   5   5

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

0 голосов
/ 08 июня 2018

Вот одна возможность, используя setNames и gsub:

# Sample data
dat <- data.frame(Foo = 1:5,Bar = 1:5)
lst <- list(dat,dat[, 2:1])

# Replace Foo with FooFoo
lst <- lapply(lst, function(x) setNames(x, gsub("^Foo$", "FooFoo", names(x))) )
#[[1]]
#  FooFoo Bar
#1      1   1
#2      2   2
#3      3   3
#4      4   4
#5      5   5
#
#[[2]]
#  Bar FooFoo
#1   1      1
#2   2      2
#3   3      3
#4   4      4
#5   5      5
0 голосов
/ 08 июня 2018

Две проблемы с вашими попытками:

  1. Странно использовать lapply(1:2, ...) вместо lapply(lst, ...).Это делает вашу анонимную функцию более неудобной.

  2. Ваша анонимная функция не return фрейм данных.Возвращается последняя строка функции (при отсутствии оператора return()).В вашей первой попытке значение последней строки - это только присвоенное значение, "new" - нам нужно вернуть весь фрейм данных с измененным именем.

Решение:

lapply(lst, function(x) {names(x)[names(x) == 'Foo'] <- 'New'; x})
# [[1]]
#   New Bar
# 1   1   1
# 2   2   2
# 3   3   3
# 4   4   4
# 5   5   5
# 
# [[2]]
#   New Bar
# 1   1   1
# 2   2   2
# 3   3   3
# 4   4   4
# 5   5   5
...