web-dev-qa-db-ja.com

lapplyを使用してデータフレームのリストの列名を変更する

データフレームのリストでlapplyを使用しようとしています。しかし、パラメーターを正しく渡すことに失敗しています(私は思います)。

データフレームのリスト:

df1 <- data.frame(A = 1:10, B= 11:20)
df2 <- data.frame(A = 21:30, B = 31:40) 

listDF <- list(df1, df2,df3)    #multiple data frames w. way less columns than the length of vector todos

列名を持つベクトル:

todos <-c('col1','col2', ......'colN')

Lapplyを使用して列名を変更したい:

lapply (listDF, function(x) { colnames(x)[2:length(x)] <-todos[1:length(x)-1] }  )

しかし、これは名前をまったく変更しません。データフレーム自体を渡すのではなく、何か他のものを渡しますか?結果を新しいオブジェクトに返すのではなく、名前を変更したいだけです。

前もって感謝します、p。

12
user3310782

すべての列を置き換える場合は、setNamesを使用することもできます

df1 <- data.frame(A = 1:10, B= 11:20)
df2 <- data.frame(A = 21:30, B = 31:40) 

listDF <- list(df1, df2)
new_col_name <- c("C", "D")

lapply(listDF, setNames, nm = new_col_name)
## [[1]]
##     C  D
## 1   1 11
## 2   2 12
## 3   3 13
## 4   4 14
## 5   5 15
## 6   6 16
## 7   7 17
## 8   8 18
## 9   9 19
## 10 10 20

## [[2]]
##     C  D
## 1  21 31
## 2  22 32
## 3  23 33
## 4  24 34
## 5  25 35
## 6  26 36
## 7  27 37
## 8  28 38
## 9  29 39
## 10 30 40

列名のサブセットのみを置き換える必要がある場合は、@ Jogoのソリューションを使用できます

lapply(listDF, function(df) {
  names(df)[-1] <- new_col_name[-ncol(df)]
  df
})

最後のポイント、Rではa:b-1とa:(b-1)の間に違いがあります

1:10 - 1
## [1] 0 1 2 3 4 5 6 7 8 9

1:(10 - 1)
## [1] 1 2 3 4 5 6 7 8 9

[〜#〜]編集[〜#〜]

グローバル環境でdata.frameの列名をリストから変更したい場合は、list2envを使用できますが、それが目的の目的を達成するための最良の方法かどうかはわかりません。また、リストを変更して名前付きリストを使用する必要があります。名前は、置き換える必要があるdata.frameの名前と同じである必要があります。

listDF <- list(df1 = df1, df2 = df2)

new_col_name <- c("C", "D")

listDF <- lapply(listDF, function(df) {
  names(df)[-1] <- new_col_name[-ncol(df)]
  df
})

list2env(listDF, envir = .GlobalEnv)
str(df1)
## 'data.frame':    10 obs. of  2 variables:
##  $ A: int  1 2 3 4 5 6 7 8 9 10
##  $ C: int  11 12 13 14 15 16 17 18 19 20
17
dickoa

これらの回答で使用されているコードを機能させることができませんでした。機能した別のフォーラムからコードを見つけました。これにより、各データフレームに新しい列名が割り当てられ、他のメソッドはデータフレームのコピーを作成しました。他の誰にとってもここにコードがあります。

# Create some dataframes
df1 <- data.frame(A = 1:10, B= 11:20)
df2 <- data.frame(A = 21:30, B = 31:40)

listDF <- c("df1", "df2") #Notice this is NOT a list
new_col_name <- c("C", "D") #What do you want the new columns to be named?

# Assign the new column names to each dataframe in "listDF"
for(df in listDF) {
  df.tmp <- get(df)
  names(df.tmp) <- new_col_name
  assign(df, df.tmp)
}
1
Patrick

これを試して:

lapply (listDF, function(x) { 
  names(x)[-1] <- todos[-length(x)]
  x 
})

データフレームが変更された新しいリストを取得します。 listDFを直接操作する場合:

for (i in 1:length(listDF)) names(listDF[[i]])[-1] <- todos[-length(listDF[[i]])]
1
jogo