Извлечение имен данных в списке и добавление их в имена столбцов. - PullRequest
0 голосов
/ 17 июня 2019

У меня есть список данных:

set.seed(23) 
date_list = seq(1:30)
testframe = data.frame(Date = date_list)
testframe$ABC = rnorm(30)
testframe$DEF = rnorm(30)
testframe$GHI = seq(from = 10, to = 25, length.out = 30)
testframe$JKL = seq(from = 5, to = 45, length.out = 30)

testlist = list(testframe, testframe, testframe)
names(testlist) = c("df1464", "df6355", "df94566")

Теперь я хочу извлечь имя каждого фрейма данных и добавить его в столбцы. Поэтому имена столбцов первого кадра данных в списке должны быть: Date_df1464, ABC_df1464, DEF_df1464, GHI_df1464 and JKL_df1464

Я создал этот цикл, но он не работает:

for (a  in names(testlist)) {
  for(i in 1: length(testlist)){
    allcolnames = colnames(testlist[[i]])
    allcolnames = paste(allcolnames, a , sep = "_")
    testlist[[i]] = colnames(allcolnames)
  }
}

Я получаю эту ошибку:

Error in testlist[[i]] : subscript out of bounds

Я совершенно не понимаю, почему это не работает. Есть идеи?

Ответы [ 3 ]

2 голосов
/ 17 июня 2019

Вы можете переключить два Map последовательно; внутренний Map подготавливает новые имена, внешний Map применяет его к именам подсписков.

testlist <- Map(`names<-`, testlist,
                Map(paste, lapply(testlist, names), names(testlist), sep="_"))

Результат

lapply(testlist, names)
# $df1464
# [1] "Date_df1464" "ABC_df1464"  "DEF_df1464"  "GHI_df1464"  "JKL_df1464" 
# 
# $df6355
# [1] "Date_df6355" "ABC_df6355"  "DEF_df6355"  "GHI_df6355"  "JKL_df6355" 
# 
# $df94566
# [1] "Date_df94566" "ABC_df94566"  "DEF_df94566"  "GHI_df94566"  "JKL_df94566" 
2 голосов
/ 17 июня 2019

Два способа сделать это. Лучшим, более инкапсулированным способом было бы использовать Map, зацикливаясь на отдельных фреймах данных и их соответствующих именах:

new.testlist <- Map(function(df, name) {
  names(df) <- paste(names(df), name, sep = '_')
  return(df)
}, testlist, names(testlist))

> str(new.testlist)
List of 3
 $ df1464 :'data.frame':    30 obs. of  5 variables:
  ..$ Date_df1464: int [1:30] 1 2 3 4 5 6 7 8 9 10 ...
  ..$ ABC_df1464 : num [1:30] 0.193 -0.435 0.913 1.793 0.997 ...
  ..$ DEF_df1464 : num [1:30] -0.5532 0.0982 -1.1467 -1.2499 -0.2021 ...
  ..$ GHI_df1464 : num [1:30] 10 10.5 11 11.6 12.1 ...
  ..$ JKL_df1464 : num [1:30] 5 6.38 7.76 9.14 10.52 ...
 $ df6355 :'data.frame':    30 obs. of  5 variables:
  ..$ Date_df6355: int [1:30] 1 2 3 4 5 6 7 8 9 10 ...
  ..$ ABC_df6355 : num [1:30] 0.193 -0.435 0.913 1.793 0.997 ...
  ..$ DEF_df6355 : num [1:30] -0.5532 0.0982 -1.1467 -1.2499 -0.2021 ...
  ..$ GHI_df6355 : num [1:30] 10 10.5 11 11.6 12.1 ...
  ..$ JKL_df6355 : num [1:30] 5 6.38 7.76 9.14 10.52 ...
 $ df94566:'data.frame':    30 obs. of  5 variables:
  ..$ Date_df94566: int [1:30] 1 2 3 4 5 6 7 8 9 10 ...
  ..$ ABC_df94566 : num [1:30] 0.193 -0.435 0.913 1.793 0.997 ...
  ..$ DEF_df94566 : num [1:30] -0.5532 0.0982 -1.1467 -1.2499 -0.2021 ...
  ..$ GHI_df94566 : num [1:30] 10 10.5 11 11.6 12.1 ...
  ..$ JKL_df94566 : num [1:30] 5 6.38 7.76 9.14 10.52 ...

Более рискованным способом было бы использовать оператор супер-присваивания для циклического перебора имен, полагая, что testlist остается надежным в вашей глобальной среде. Обратите внимание, что этот второй метод изменяет имена столбцов в testlist как побочный эффект и, как правило, НЕ считается хорошей практикой. Ответ Макса Тефлона несколько схож с тем, что он опирается на testlist, существующий в глобальной среде, без явной передачи его модифицирующей функции.

sapply(names(testlist), function(x) {
  names(testlist[[x]]) <<- paste(names(testlist[[x]]), x, sep = '_')
})
1 голос
/ 17 июня 2019

Ваше решение было почти правильным, вам просто не нужно повторять два раза. И ваш colnames звонок был неправильным. Это должно работать:

for(i in 1: length(testlist)){
    allcolnames = colnames(testlist[[i]])
    allcolnames = paste(allcolnames, names(testlist)[i] , sep = "_")
    colnames(testlist[[i]]) = allcolnames
}

Это тоже работает, без форса;):

set.seed(23) 
date_list = seq(1:30)
testframe = data.frame(Date = date_list)
testframe$ABC = rnorm(30)
testframe$DEF = rnorm(30)
testframe$GHI = seq(from = 10, to = 25, length.out = 30)
testframe$JKL = seq(from = 5, to = 45, length.out = 30)

testlist = list(testframe, testframe, testframe)
names(testlist) = c("df1464", "df6355", "df94566")

out <- lapply(names(testlist),function(name){
  dummy <- testlist[[name]]
  names(dummy) <- paste0(names(testlist[[name]]) ,'_',name)
  dummy
})
str(out)
#> List of 3
#>  $ :'data.frame':    30 obs. of  5 variables:
#>   ..$ Date_df1464: int [1:30] 1 2 3 4 5 6 7 8 9 10 ...
#>   ..$ ABC_df1464 : num [1:30] 0.193 -0.435 0.913 1.793 0.997 ...
#>   ..$ DEF_df1464 : num [1:30] -0.5532 0.0982 -1.1467 -1.2499 -0.2021 ...
#>   ..$ GHI_df1464 : num [1:30] 10 10.5 11 11.6 12.1 ...
#>   ..$ JKL_df1464 : num [1:30] 5 6.38 7.76 9.14 10.52 ...
#>  $ :'data.frame':    30 obs. of  5 variables:
#>   ..$ Date_df6355: int [1:30] 1 2 3 4 5 6 7 8 9 10 ...
#>   ..$ ABC_df6355 : num [1:30] 0.193 -0.435 0.913 1.793 0.997 ...
#>   ..$ DEF_df6355 : num [1:30] -0.5532 0.0982 -1.1467 -1.2499 -0.2021 ...
#>   ..$ GHI_df6355 : num [1:30] 10 10.5 11 11.6 12.1 ...
#>   ..$ JKL_df6355 : num [1:30] 5 6.38 7.76 9.14 10.52 ...
#>  $ :'data.frame':    30 obs. of  5 variables:
#>   ..$ Date_df94566: int [1:30] 1 2 3 4 5 6 7 8 9 10 ...
#>   ..$ ABC_df94566 : num [1:30] 0.193 -0.435 0.913 1.793 0.997 ...
#>   ..$ DEF_df94566 : num [1:30] -0.5532 0.0982 -1.1467 -1.2499 -0.2021 ...
#>   ..$ GHI_df94566 : num [1:30] 10 10.5 11 11.6 12.1 ...
#>   ..$ JKL_df94566 : num [1:30] 5 6.38 7.76 9.14 10.52 ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...