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

Цель: изменить имена столбцов всех фреймов данных в глобальной среде из следующего списка

colnames тех, что в глобальной среде

So.

0) Имена столбцов:

 colnames = c("USAF","WBAN","YR--MODAHRMN") 

1) Имею следующие data.frames: df1, df2.

2) Я помещаю их в список:

  dfList <- list(df1,df2)

3) Прокрутите список:

 for (df in dfList){
   colnames(df)=colnames
 }

Но это создает новый df с нужными мне именами столбцов, он не меняет исходные имена столбцов в df1, df2. Почему? Может ли это быть решением? Спасибо

Может что-то вроде:

 lapply(dfList, function(x) {colnames(dfList)=colnames})

Работа?


person Oniropolo    schedule 21.02.2015    source источник


Ответы (4)


С lapply это можно сделать следующим образом.

Создайте образец данных:

df1 <- data.frame(A = 1, B = 2, C = 3)
df2 <- data.frame(X = 1, Y = 2, Z = 3)
dfList <- list(df1,df2)
colnames <- c("USAF","WBAN","YR--MODAHRMN") 

Затем пролистайте список, используя setNames, и укажите вектор новых имен столбцов в качестве второго аргумента для setNames:

lapply(dfList, setNames, colnames)
#[[1]]
#  USAF WBAN YR--MODAHRMN
#1    1    2            3
#
#[[2]]
#  USAF WBAN YR--MODAHRMN
#1    1    2            3

Редактировать

Если вы хотите вернуть data.frames в глобальную среду, вы можете изменить код следующим образом:

dfList <- list(df1 = df1, df2 = df2)
list2env(lapply(dfList, setNames, colnames), .GlobalEnv)
person talat    schedule 21.02.2015
comment
@Oniropolo, см. Мою правку. Это изменит ваши исходные data.frames в глобальной среде. - person talat; 21.02.2015
comment
Это способ продвинуть мои знания R, но я читал о средах. Могу я вас спросить, почему 1) вы не создали новую среду вместо списка? 2) Предположим, вам нужно выполнить некоторую очистку данных, например strptime (df1 $ YR - MODAHRMN, format = '% Y% m% d% H% M'). Можно ли создать среду, а затем изменить все элементы в этой новой среде? Извините за недостаток знаний! - person Oniropolo; 21.02.2015
comment
@Oniropolo, ваш вопрос был основан на наличии списка data.frames, в котором вы хотите изменить имена - поэтому я использовал структуру списка .. Обычно, если у вас много data.frames, которые так или иначе связаны, лучше их оставить в списке (т.е. не возвращать их в глобальную среду). Как правило, я почти никогда не создаю дополнительных сред, но это, как мне кажется, зависит от личных предпочтений в программировании. - person talat; 21.02.2015
comment
Большое спасибо! Я не знал, что это за среда до вашего ответа! - person Oniropolo; 21.02.2015

Просто измените цикл for на цикл индекса for, например:

Данные

df1 <- data.frame(a=runif(5), b=runif(5), c=runif(5))
df2 <- data.frame(a=runif(5), b=runif(5), c=runif(5))

dflist <- list(df1,df2)

colnames = c("USAF","WBAN","YR--MODAHRMN") 

Решение

for (i in seq_along(dflist)){
  colnames(dflist[[i]]) <- colnames
}

Выход

> dflist
[[1]]
       USAF      WBAN YR--MODAHRMN
1 0.8794153 0.7025747    0.2136040
2 0.8805788 0.8253530    0.5467952
3 0.1719539 0.5303908    0.5965716
4 0.9682567 0.5137464    0.4038919
5 0.3172674 0.1403439    0.1539121

[[2]]
        USAF       WBAN YR--MODAHRMN
1 0.20558383 0.62651334    0.4365940
2 0.43330717 0.85807280    0.2509677
3 0.32614750 0.70782919    0.6319263
4 0.02957656 0.46523151    0.2087086
5 0.58757198 0.09633181    0.6941896

Используя for (df in dfList), вы, по сути, каждый раз создаете новый df и меняете имена столбцов на те, которые оставляют исходный список (dfList) нетронутым.

person LyzandeR    schedule 21.02.2015
comment
Почему тогда ... ›colnames (df2) возвращает исходный [1] a b c? - person Oniropolo; 21.02.2015
comment
Потому что изменяемые data.frames - это те, которые находятся в списке, а не те, которые находятся за пределами списка. Если вы сделаете colnames(df2), вы получите исходные имена, потому что с df2 ничего не произошло. Вместо этого сделайте colnames(dflist[[2]]), чтобы увидеть результат. df2 - второй элемент в списке, и это то, что изменилось. Вы можете сделать df2 <- dflist[[2]], если захотите потом. - person LyzandeR; 21.02.2015
comment
Тогда возникает вопрос, как изменить исходный df2? Имеются значения исходные столбцы df1, df2; список - это просто способ изменения обоих в одном цикле. - person Oniropolo; 21.02.2015
comment
Я предоставил решение выше :): df2 <- dflist[[2]] - person LyzandeR; 21.02.2015
comment
Ооо, самая простая из возможных линий. Как мне это не пришло в голову. Спасибо! - person Oniropolo; 21.02.2015
comment
Не стоит беспокоиться. Взгляните на решение @docendodiscimus выше. Он немного более продвинутый, но, возможно, стоит изучить его. - person LyzandeR; 21.02.2015
comment
@Oniropolo, пожалуйста, отредактируйте первую строку вашего вопроса, чтобы отразить, что это не data.frames в списке, для которого вы хотите изменить имена столбцов, а имена столбцов в глобальной среде. - person StrikeR; 21.02.2015

Если вы хотите, чтобы цикл for работал, вы не должны передавать весь data.frame в качестве аргумента.

for (df in 1:length(dfList))
  colnames(dfList[[df]]) <- colnames
person StrikeR    schedule 21.02.2015
comment
Я действительно не понимаю ... Так, например, используя пример, который дал первый человек, с вашим кодом я все еще получаю colnames (df2) ... [1] X Y Z - person Oniropolo; 21.02.2015
comment
В том ответе, о котором вы говорите, df2 - это data.frame, который не имеет ничего общего с dfList, который представляет собой комбинацию df1 и df2. Итак, имена изменены в df2, который присутствует внутри dfList. Посмотрите на colnames(dfList$df2), чтобы узнать об измененных именах столбцов. - person StrikeR; 21.02.2015

person    schedule
comment
Хотя этот фрагмент кода может решить вопрос, включение объяснения действительно помогает улучшить качество вашего поста. Помните, что вы отвечаете на вопрос для читателей в будущем, и эти люди могут не знать причины вашего предложения кода. - person Gerhard; 05.07.2021
comment
Может быть ... все же лучше принятого решения :) - person Dan Lewer; 05.07.2021