Dataframes в списке; добавление новой переменной с именем dataframe
у меня есть список фреймов данных, которые я в конечном итоге хочу объединить, сохраняя запись их исходного имени фрейма данных или индекса списка. Это позволит мне подмножество etc по всем строкам. Для этого я хотел бы добавить новую переменную " id " к каждому фрейму данных, который содержит имя/индекс фрейма данных, к которому он принадлежит.
Edit: "в моем реальном коде переменные dataframe создаются из чтения нескольких файлов, используя следующий код, поэтому у меня нет фактического называет только те, что в файлах.на.прочитайте " список, который я не уверен, будут ли они соответствовать порядку фрейма данных:
mylist <- llply(files.to.read, read.csv)
несколько методов были выделены несколько постов: работа-с-dataframes-в-список-падение-переменные-добавить-новые-те и использование-lapply-with-changing-arguments
Я пробовал два аналогичных метода, первый из которых использует список индексов:
df1 <- data.frame(x=c(1:5),y=c(11:15))
df2 <- data.frame(x=c(1:5),y=c(11:15))
mylist <- list(df1,df2)
# Adds a new coloumn 'id' with a value of 5 to every row in every dataframe.
# I WANT to change the value based on the list index.
mylist1 <- lapply(mylist,
function(x){
x$id <- 5
return (x)
}
)
#Example of what I WANT, instead of '5'.
#> mylist1
#[[1]]
#x y id
#1 1 11 1
#2 2 12 1
#3 3 13 1
#4 4 14 1
#5 5 15 1
#
#[[2]]
#x y id
#1 1 11 2
#2 2 12 2
#3 3 13 2
#4 4 14 2
#5 5 15 2
вторая попытка передать имена() список.
# I WANT it to add a new coloumn 'id' with the name of the respective dataframe
# to every row in every dataframe.
mylist2 <- lapply(names(mylist),
function(x){
portfolio.results[[x]]$id <- "dataframe name here"
return (portfolio.results[[x]])
}
)
#Example of what I WANT, instead of 'dataframe name here'.
# mylist2
#[[1]]
#x y id
#1 1 11 df1
#2 2 12 df1
#3 3 13 df1
#4 4 14 df1
#5 5 15 df1
#
#[[2]]
#x y id
#1 1 11 df2
#2 2 12 df2
#3 3 13 df2
#4 4 14 df2
#5 5 15 df2
но функция names () не работает в списке фреймов данных; она возвращает NULL. Могу ли я использовать seq_along(mylist) в первом примере.
любые идеи или лучший способ обработки всего "слияния с исходным кодом"
Edit-добавлено Решение ниже: я реализовал решение, используя предложение Хэдли и подталкивание Томми, которое выглядит примерно так.
files.to.read <- list.files(datafolder, pattern="_D.csv$", full.names=FALSE)
mylist <- llply(files.to.read, read.csv)
all <- do.call("rbind", mylist)
all$id <- rep(files.to.read, sapply(mylist, nrow))
я использовал файлы.на.прочитайте вектор как id для каждого таблицы данных
Я также изменил использование merge_recurse (), поскольку по какой-то причине он был очень медленным.
all <- merge_recurse(mylist)
спасибо всем.
4 ответов
лично я думаю, что легче добавить имена после коллапса:
df1 <- data.frame(x=c(1:5),y=c(11:15))
df2 <- data.frame(x=c(1:5),y=c(11:15))
mylist <- list(df1 = df1, df2 = df2)
all <- do.call("rbind", mylist)
all$id <- rep(names(mylist), sapply(mylist, nrow))
ваша первая попытка была очень близка. Используя индексы вместо значений, он будет работать. Ваша вторая попытка не удалась, потому что вы не назвали элементы в своем списке.
оба решения ниже используют тот факт, что lapply
может передавать дополнительные параметры (mylist) в функцию.
df1 <- data.frame(x=c(1:5),y=c(11:15))
df2 <- data.frame(x=c(1:5),y=c(11:15))
mylist <- list(df1=df1,df2=df2) # Name each data.frame!
# names(mylist) <- c("df1", "df2") # Alternative way of naming...
# Use indices - and pass in mylist
mylist1 <- lapply(seq_along(mylist),
function(i, x){
x[[i]]$id <- i
return (x[[i]])
}, mylist
)
# Now the names work - but I pass in mylist instead of using portfolio.results.
mylist2 <- lapply(names(mylist),
function(n, x){
x[[n]]$id <- n
return (x[[n]])
}, mylist
)
names()
может работать, у него были имена, но вы не дали ему ни одного. Это неназванный список. Вам понадобится ti использовать числовые индексы:
> for(i in 1:length(mylist) ){ mylist[[i]] <- cbind(mylist[[i]], id=rep(i, nrow(mylist[[i]]) ) ) }
> mylist
[[1]]
x y id
1 1 11 1
2 2 12 1
3 3 13 1
4 4 14 1
5 5 15 1
[[2]]
x y id
1 1 11 2
2 2 12 2
3 3 13 2
4 4 14 2
5 5 15 2
dlply форма функция plyr пакет может быть ответом:
library('plyr')
df1 <- data.frame(x=c(1:5),y=c(11:15))
df2 <- data.frame(x=c(1:5),y=c(11:15))
mylist <- list(df1 = df1, df2 = df2)
all <- ldply(mylist)