我对R来说比较新,并试图弄清楚如何将列表列表转换为单个数据库。列表列表是从我在一个名为NetLogo的独立平台中开发的模型的并行处理生成的。扩展RNetLogo允许两者进行通信。用于并行化函数的代码是:
sim <- function(y){
results=list()
NLCommand("setup")
ret <- NLDoReport(48,"go", "count breeding-males + count breeding-females", as.data.frame=TRUE, df.col.names=c("breeding.animals"));
ret1 <-NLReport("mean male-land-tenure-list")
names(ret1) <- c("male.land.tenure")
results[[1]]=ret
results[[2]]=ret1
return(results)
}
repetitions <- 1:16
clusterExport(cl, 'sim')
results.test <-parSapply(cl, repetitions, function(y){sim()})
print(data.frame(results.test))
输出results.test
包含我需要的所有结果。 results.test
的示例如下:
X1
1 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, 61, 63, 66, 66, 66, 67
2
27.4
X2
1 ...
数据的结构str
为:
List of 32
$ :List of 48
$ : num 27.4
...
X1
,X2
,X3
...是运行数字。每个运行都会关联两个列表(ret
和ret1
)。
但我想像下面一样将所有这些组合在一起,第一列是运行编号。在这种情况下,它将是1 - 16.下一列将是time.step,在这种情况下从1-48开始。最后,48长度ret
将是&#34; breeding.adults&# 34 ;.理想情况下,我希望将输出ret1
(male.land.tenure)保存在一个单独的数据框中,该数据框显示它所属的运行编号。基本上,任何有关如何从列表中获取数据以及使用可用数据帧的建议都将非常受欢迎。
run.number time.step breeding.adults
1 0 58
2 0 58
1 1 58
4 0 58
3 0 58
2 1 58
4 1 58
3 1 58
1 2 58
2 2 58
4 2 58
答案 0 :(得分:3)
这是一种直接生成所需data.frame
s(data.table
s)的方法。
melt
函数(我们使用list
方法)和getanID
函数的“splitstackshape”包需要“reshape2”。
library(splitstackshape)
library(reshape2)
从那里开始,在1:2的序列中,它是一个简单的lapply
,因为我们知道我们希望第一个子列表项为一个data.frame
,第二个子列表项为另一个data.frame
:
lapply(1:2, function(x) getanID(melt(lapply(L, "[[", x)), "L1"))
# [[1]]
# value L1 .id
# 1: 3 1 1
# 2: 4 1 2
# 3: 5 1 3
# 4: 7 1 4
# 5: 2 1 5
# 6: 8 1 6
# 7: 9 1 7
# 8: 6 1 8
# 9: 10 1 9
# 10: 1 1 10
# 11: 3 2 1
# 12: 10 2 2
# 13: 5 2 3
# 14: 14 2 4
# 15: 6 2 5
# 16: 8 2 6
# 17: 9 2 7
# 18: 4 2 8
# 19: 11 2 9
# 20: 7 2 10
# 21: 2 2 11
# 22: 15 2 12
# 23: 1 2 13
# 24: 12 2 14
# 25: 13 2 15
# value L1 .id
#
# [[2]]
# value L1
# 1: 0.20597457 1
# 2: 0.01339033 2
此处所需的唯一真正先决条件知识是,当您melt
列表时,值会出现在一列中(名为“value”),而其他列则以“L1”,“L1”的命名模式创建L2“等等,用于嵌套列表。由于我们没有处理任何嵌套,我们知道我们只能使用“L1”来生成我们的ID。
此答案使用来自@ jbaums答案的L
set.seed(1)
作为样本数据。
答案 1 :(得分:1)
如果我理解正确,则列表元素代表单个运行,1到length(results.test)
,results.test
每个元素的第一个元素包含跨时间步长的繁殖成年人数。< / p>
要将这些绑定到一个数据框中,您可以使用:
# Create an example list with equivalent structure
L <- list(list(sample(10), runif(1)), list(sample(15), runif(1)))
# Simplify the list to just the breeding adults elements
breeding_adults <- lapply(L, '[[', 1)
# Bind together the relevant information
cbind(run=unlist(mapply(rep, seq_along(breeding_adults),
each=sapply(breeding_adults, length))),
timestep=unlist(sapply(breeding_adults, seq_along)),
n=unlist(breeding_adults))
# run timestep n
# [1,] 1 1 10
# [2,] 1 2 3
# [3,] 1 3 6
# [4,] 1 4 7
# [5,] 1 5 4
# [6,] 1 6 8
# [7,] 1 7 9
# [8,] 1 8 1
# [9,] 1 9 2
# [10,] 1 10 5
# [11,] 2 1 5
# [12,] 2 2 12
# [13,] 2 3 3
# [14,] 2 4 6
# [15,] 2 5 2
# [16,] 2 6 10
# [17,] 2 7 13
# [18,] 2 8 9
# [19,] 2 9 8
# [20,] 2 10 14
# [21,] 2 11 15
# [22,] 2 12 11
# [23,] 2 13 4
# [24,] 2 14 1
# [25,] 2 15 7
答案 2 :(得分:1)
我生成了一个样本数据集来解决这个问题:
a <- list(list(as.list(1:4),5),list(as.list(11:14),6))
重新格式化ret
的代码:
rets <- lapply(a,`[[`,1)
names(rets) <- paste0(seq_along(rets),'_')
un <- unlist(rets)
d <- data.frame(do.call(rbind,strsplit(names(un),'_')),breeding.adults=un)
colnames(d)[1:2] <- c('run.number', 'time.step')
重新格式化ret1
的代码:
rets1 <- lapply(a,`[[`,2)
data.frame(run.number=seq_along(rets1),male.land.tenure=unlist(rets1))
我希望此解决方案也适用于您的数据集。