NetLogo - 使用 BehaviorSpace 获取所有海龟位置作为每次重复的结果
NetLogo - using BehaviorSpace get all turtles locations as the result of each repetition
我正在使用 BehaviorSpace 运行 使用不同参数的模型数百次。但是我需要知道所有海龟的位置,而不仅仅是海龟的数量。如何使用 BehaviorSpace 实现它?
目前,我通过以下代码将结果输出到csv文件中:
to-report get-locations
report (list xcor ycor)
end
to generate-output
file-open "model_r_1.0_locations.csv"
file-print csv:to-row get-locations
file-close
end
但所有结果都弹出到同一个 csv 文件中,所以我无法分辨每个 运行ning 的情况。
Seth 关于在 csv
输出的文件名中加入 behaviorspace-run-number
的建议是一种选择。它允许您将该文件与主 BehaviorSpace 输出文件中的摘要数据相关联。
另一种选择是在您的行为 space 实验定义中将报告者列为 "measures"。例如,在您的情况下:
map [ t -> [ xcor ] of t ] sort turtles
map [ t -> [ ycor ] of t ] sort turtles
然后您可以用您最喜欢的数据分析语言解析结果列表 "manually"。我之前在 Julia 中为此使用了以下函数:
parselist(strlist, T = Float64) = parse.(T, split(strlist[2:end-1]))
我相信您可以轻松地用 Python 或 R 或您使用的任何语言编写一些等效代码。
在上面的示例中,我为海龟的 xcor
和 ycor
输出了单独的列表。您也可以输出单个 "list of lists",但解析会比较棘手。
编辑:如何使用 csv
扩展和 R
来做到这一点
巧合的是,今天我不得不为另一个项目做类似的事情,我意识到 csv
extension 和 R 的组合可以使这变得非常容易。
大致思路如下:
在 NetLogo 中,使用 csv:to-string
将列表数据编码为字符串,然后将该字符串直接写入 BehaviorSpace 输出。
在 R 中,使用 purrr::map
and readr::read_csv
, followed by tidyr::unnest
,将所有内容解压到一个整洁的 "one observation per row" 数据帧中。
换句话说:我们喜欢 CSV,所以我们将 CSV 放在 CSV 中,这样我们就可以边解析边解析。
这是一个完整的例子。假设我们有以下 NetLogo 模型:
extensions [ csv ]
to setup
clear-all
create-turtles 2 [ move-to one-of patches ]
reset-ticks
end
to go
ask turtles [ forward 1 ]
tick
end
to-report positions
let coords [ (list who xcor ycor) ] of turtles
report csv:to-string fput ["who" "x" "y"] coords
end
然后我们使用我们的 positions
报告器作为输出来定义以下微型行为空间实验,只有两次重复和两次时间限制:
处理此问题的 R 代码非常简单:
library(tidyverse)
df <- read_csv("experiment-table.csv", skip = 6) %>%
mutate(positions = map(positions, read_csv)) %>%
unnest()
这会产生以下数据框,一切都很整洁:
> df
# A tibble: 12 x 5
`[run number]` `[step]` who x y
<int> <int> <int> <dbl> <dbl>
1 1 0 0 16 10
2 1 0 1 10 -2
3 1 1 1 9.03 -2.24
4 1 1 0 -16.0 10.1
5 1 2 1 8.06 -2.48
6 1 2 0 -15.0 10.3
7 2 0 1 -14 1
8 2 0 0 13 15
9 2 1 0 14.0 15.1
10 2 1 1 -13.7 0.0489
11 2 2 0 15.0 15.1
12 2 2 1 -13.4 -0.902
Julia 中同样的事情:
using CSV, DataFrames
df = CSV.read("experiment-table.csv", header = 7)
cols = filter(col -> col != :positions, names(df))
df = by(df -> CSV.read(IOBuffer(df[:positions][1])), df, cols)
我正在使用 BehaviorSpace 运行 使用不同参数的模型数百次。但是我需要知道所有海龟的位置,而不仅仅是海龟的数量。如何使用 BehaviorSpace 实现它?
目前,我通过以下代码将结果输出到csv文件中:
to-report get-locations
report (list xcor ycor)
end
to generate-output
file-open "model_r_1.0_locations.csv"
file-print csv:to-row get-locations
file-close
end
但所有结果都弹出到同一个 csv 文件中,所以我无法分辨每个 运行ning 的情况。
Seth 关于在 csv
输出的文件名中加入 behaviorspace-run-number
的建议是一种选择。它允许您将该文件与主 BehaviorSpace 输出文件中的摘要数据相关联。
另一种选择是在您的行为 space 实验定义中将报告者列为 "measures"。例如,在您的情况下:
map [ t -> [ xcor ] of t ] sort turtles
map [ t -> [ ycor ] of t ] sort turtles
然后您可以用您最喜欢的数据分析语言解析结果列表 "manually"。我之前在 Julia 中为此使用了以下函数:
parselist(strlist, T = Float64) = parse.(T, split(strlist[2:end-1]))
我相信您可以轻松地用 Python 或 R 或您使用的任何语言编写一些等效代码。
在上面的示例中,我为海龟的 xcor
和 ycor
输出了单独的列表。您也可以输出单个 "list of lists",但解析会比较棘手。
编辑:如何使用 csv
扩展和 R
来做到这一点
巧合的是,今天我不得不为另一个项目做类似的事情,我意识到 csv
extension 和 R 的组合可以使这变得非常容易。
大致思路如下:
在 NetLogo 中,使用
csv:to-string
将列表数据编码为字符串,然后将该字符串直接写入 BehaviorSpace 输出。在 R 中,使用
purrr::map
andreadr::read_csv
, followed bytidyr::unnest
,将所有内容解压到一个整洁的 "one observation per row" 数据帧中。
换句话说:我们喜欢 CSV,所以我们将 CSV 放在 CSV 中,这样我们就可以边解析边解析。
这是一个完整的例子。假设我们有以下 NetLogo 模型:
extensions [ csv ]
to setup
clear-all
create-turtles 2 [ move-to one-of patches ]
reset-ticks
end
to go
ask turtles [ forward 1 ]
tick
end
to-report positions
let coords [ (list who xcor ycor) ] of turtles
report csv:to-string fput ["who" "x" "y"] coords
end
然后我们使用我们的 positions
报告器作为输出来定义以下微型行为空间实验,只有两次重复和两次时间限制:
处理此问题的 R 代码非常简单:
library(tidyverse)
df <- read_csv("experiment-table.csv", skip = 6) %>%
mutate(positions = map(positions, read_csv)) %>%
unnest()
这会产生以下数据框,一切都很整洁:
> df
# A tibble: 12 x 5
`[run number]` `[step]` who x y
<int> <int> <int> <dbl> <dbl>
1 1 0 0 16 10
2 1 0 1 10 -2
3 1 1 1 9.03 -2.24
4 1 1 0 -16.0 10.1
5 1 2 1 8.06 -2.48
6 1 2 0 -15.0 10.3
7 2 0 1 -14 1
8 2 0 0 13 15
9 2 1 0 14.0 15.1
10 2 1 1 -13.7 0.0489
11 2 2 0 15.0 15.1
12 2 2 1 -13.4 -0.902
Julia 中同样的事情:
using CSV, DataFrames
df = CSV.read("experiment-table.csv", header = 7)
cols = filter(col -> col != :positions, names(df))
df = by(df -> CSV.read(IOBuffer(df[:positions][1])), df, cols)