使用R base,我想将一个变量添加到嵌套列表中,其中变量为每个嵌套列表元素更改.以下是一个例子.谢谢.
#CREATE EXAMPLE DATAFRAME
DF <- expand.grid(NAME = c("FRANK", "TONY", "ED"), DATE = seq(as.Date("2014-01-01"), as.Date("2018-12-31"), by = "day"))
#CREATE NESTED LIST
DF <- lapply(1:3, function(i) lapply(2014:2015, function(t) DF[with(DF, as.Date(paste(t, "01", "01", sep = "-")) <= DATE & DATE <= as.Date(paste(t + i, "12", "31", sep = "-"))), ]))
#PRINT NESTED LIST
lapply(DF, lapply, function(x) rbind(head(x), tail(x)))
#I WOULD LIKE TO SIMPLIFY THIS PART
DF[[1]][[1]] <- within(DF[[1]][[1]], GROUP <- 2014)
DF[[1]][[2]] <- within(DF[[1]][[2]], GROUP <- 2015)
DF[[2]][[1]] <- within(DF[[2]][[1]], GROUP <- 2014)
DF[[2]][[2]] <- within(DF[[2]][[2]], GROUP <- 2015)
DF[[3]][[1]] <- within(DF[[3]][[1]], GROUP <- 2014)
DF[[3]][[2]] <- within(DF[[3]][[2]], GROUP <- 2015)
#PRINT MODIFIED NESTED LIST
lapply(DF, lapply, function(x) rbind(head(x), tail(x)))
#I AM SURPRISED THE FOLLOWING DOES NOT WORK
DF <- expand.grid(NAME = c("FRANK", "TONY", "ED"), DATE = seq(as.Date("2014-01-01"), as.Date("2018-12-31"), by = "day"))
DF <- lapply(1:3, function(i) lapply(2014:2015, function(t) DF[with(DF, as.Date(paste(t, "01", "01", sep = "-")) <= DATE & DATE <= as.Date(paste(t + i, "12", "31", sep = "-"))),]))
DF <- lapply(DF, function(x) lapply(2014:2015, function(t) within(x, GROUP <- t)))
lapply(DF, lapply, function(x) rbind(head(x), tail(x)))
Run Code Online (Sandbox Code Playgroud)
这应该做到这一点
final_list<-list()
for(i in seq(1, length(DF))){
new_list<-list()
for(j in seq(1,length(DF[[i]]))){
new_list[[j]]<-list(DF[[i]][[j]],GROUP=j)
}
final_list[[i]]<-new_list
}
Run Code Online (Sandbox Code Playgroud)
#CREATE EXAMPLE DATAFRAME
DF <- expand.grid(NAME = c("FRANK", "TONY", "ED"), DATE = seq(as.Date("2014-01-01"), as.Date("2018-12-31"), by = "day"))
#CREATE NESTED LIST
DF <- lapply(1:3, function(i) lapply(2014:2015, function(t) DF[with(DF, as.Date(paste(t, "01", "01", sep = "-")) <= DATE & DATE <= as.Date(paste(t + i, "12", "31", sep = "-"))), ]))
#PRINT NESTED LIST
lapply(DF, lapply, function(x) rbind(head(x), tail(x)))
#I WOULD LIKE TO SIMPLIFY THIS PART
DF[[1]][[1]] <- within(DF[[1]][[1]], GROUP <- 2014)
DF[[1]][[2]] <- within(DF[[1]][[2]], GROUP <- 2015)
DF[[2]][[1]] <- within(DF[[2]][[1]], GROUP <- 2014)
DF[[2]][[2]] <- within(DF[[2]][[2]], GROUP <- 2015)
DF[[3]][[1]] <- within(DF[[3]][[1]], GROUP <- 2014)
DF[[3]][[2]] <- within(DF[[3]][[2]], GROUP <- 2015)
#PRINT MODIFIED NESTED LIST
DF1 <- lapply(DF, lapply, function(x) rbind(head(x), tail(x)))
DF1
#I AM SURPRISED THE FOLLOWING DOES NOT WORK
DF <- expand.grid(NAME = c("FRANK", "TONY", "ED"), DATE = seq(as.Date("2014-01-01"), as.Date("2018-12-31"), by = "day"))
DF <- lapply(1:3, function(i) lapply(2014:2015, function(t) DF[with(DF, as.Date(paste(t, "01", "01", sep = "-")) <= DATE & DATE <= as.Date(paste(t + i, "12", "31", sep = "-"))),]))
GROUPS <- c(2014:2015)
DF <- lapply(DF, function(xs) lapply(1:2, function(t) within(xs[[t]], GROUP <- GROUPS[t])))
DF2 <- lapply(DF, lapply, function(x) rbind(head(x), tail(x)))
DF2
all.equal(DF1, DF2)
Run Code Online (Sandbox Code Playgroud)
我认为问题可能是第二个lapply:
DF <- lapply(DF, function(x) lapply(2014:2015, function(t) within(x, GROUP <- t)))
Run Code Online (Sandbox Code Playgroud)
似乎lapply没有从大列表对象中提取所需的组件。第一个lapply迭代列表的顶层,x每次提取一个二元素列表对象 。然后第二个lapply迭代向量,t每次都提供标量向量 。x因此,下一部分每次都会获取一个二元素列表 ( ),而不是所需的(未命名)数据框。
如果对象已经创建,您可以直接迭代元素,而不是索引列表元素。
#CREATE NESTED LIST
DF <- lapply(1:3, function(i) lapply(2014:2015, function(t) DF[with(DF, as.Date(paste(t, "01", "01", sep = "-")) <= DATE & DATE <= as.Date(paste(t + i, "12", "31", sep = "-"))), ]))
edit_level2 <- function(df) {
# figure out what the value of t should be based on the data.
t <- as.integer(format(min(df$DATE), "%Y"))
df$GROUP <- t
return(df)
}
# iterate over the list object contents at *both* levels
DF <- lapply(DF, function(level1) lapply(level1, function(level2) edit_level2(level2)))
Run Code Online (Sandbox Code Playgroud)
注意:这类似于@Consistency在评论中提出的解决方案——提取数据帧是问题。
如果您可以更改生成列表对象的代码,我建议在创建列表对象时分配变量,而不是事后修改它(我在编辑之前的原始建议)。
#CREATE EXAMPLE DATAFRAME
DF <- expand.grid(NAME = c("FRANK", "TONY", "ED"),
DATE = seq(as.Date("2014-01-01"), as.Date("2018-12-31"), by = "day"))
#CREATE NESTED LIST
DF <- lapply(1:3, function(i) {
lapply(2014:2015, function(t) {
first <- as.Date(paste(t, "01", "01", sep = "-"))
last <- as.Date(paste(t + i, "12", "31", sep = "-"))
# create a local data frame
df <- DF[first <= DF$DATE & DF$DATE <= last, ]
# modify the local data frame
df$GROUP <- t
# return the modified data frame
df
})
})
Run Code Online (Sandbox Code Playgroud)