簡體   English   中英

更改R中數據框列表中的列名稱子集

[英]Changing a subset of column names in a list of data frames in R

此問題是R中數據框列表中更改列名的擴展。

該帖子解決了更改data.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

(失敗)嘗試:

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'))

這是使用setNamesgsub一種可能性:

# 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

您嘗試的兩個問題:

  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

這是一種按列索引更改列名稱的方法。

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

在我看到OP的更新評論之前我發布了這個答案,他說每個數據框的目標列的索引可能不同。 原帖中沒有提到這一點。 請查看其他人的帖子,因為我的答案僅在列索引一致時才有效。

我的解決方案比其他解決方案更復雜,但事實如此。

主要區別在於它不使用==而是使用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

使用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

這里通過引用進行更改,因此我們首先進行復制。

注意沒有賦值,它不會更改原始對象。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM