首页 > 解决方案 > How to read in a file, run a simulation, then read in the next file and repeat simulation

问题描述

For the code below, I am trying to serially read in .txt files created in r and output to my working directory (containing both Netlogo and R scripts) into NetLogo. The files are essentially ascii grid files whose numbers are assigned to patches to generate landscapes by coloring patches according to the numbers in grid cells from the text file. The NetLogo code executes this with a simple Setup button.

patches-own [
  landcover
]

to setup ; procedure to reset netlogo interface once setup button is pressed after one run of various code procedures
  ca ; clears the world
  resize-world 0 600 -600 0
  generate-landscape
  reset-ticks
end

to generate-landscape
  file-open "landscape.txt"
  foreach sort patches [
  the-patch ->
  ask the-patch [ ; read a data element into a patch variable
      set landcover file-read ; color the patch accordingly
      if (landcover = 1) [
        set pcolor green
          ]
      if (landcover = 0.5) [
        set pcolor orange
          ]
      if (landcover = 0) [
        set pcolor grey
          ]
        ]
      ]
   file-close
end

My question is, what if I have multiple such ascii grid .txt files in the working directory, each representing a new/different landscape and I want to read them into NetLogo to perform some simulation one at a time? Is there a good and efficient way/code to do this?

标签: netlogo

解决方案


If you have a common filename (eg. "terrain1.asc", "terrain2.asc", etc) that you can just iterate through with foreach that may be easiest. Otherwise, you may be able to use the r extension, something like this:

extensions [r csv]

globals [ list-of-file-names ]

to setup
  ca
  r:eval "x <- list.files('absolute_folder_path_here')" 
  set list-of-file-names r:get "x"
  reset-ticks
end

to go 
  foreach list-of-file-names [
    fname ->
    let fpath word "absolute_folder_path_here" fname
    print csv:from-file fpath
  ]
end

In the example above, I have three different .csv files in a folder. I provide the absolute address to that folder to the list.files function called in R to get the list of file names saved as a list, then I can use foreach to iterate over each file and do whatever you need.

extensions [r csv]

globals [ 
  list-of-file-names 
  numbers
]

to setup  
  ca
  r:eval "x <- list.files('C:/Users/lukepc/Google Drive/school_2017/nlogo_examples/textfiles')"
  set list-of-file-names r:get "x"
  reset-ticks
end

to scheduler
  foreach list-of-file-names [
    fname ->
    ; Reset the world
    limited-reset

    ; Load the new file/data
    let fpath word "C:/Users/lukepc/Google Drive/school_2017/nlogo_examples/textfiles/" fname
    set numbers csv:from-file fpath

    ; Do your model procedures
    go
  ]
end

to limited-reset
  ; Reset all variables (except list-of-file-names) here
  ; and otherwise return your model to its base state
end


to go
  ; Do the regular model processes as normal
end

Edit:

Stealing from Brian Head here- if he puts up this answer I will remove mine!

If you want to use BehaviorSpace, which would be far easier assuming a simple naming convention, you could do a setup like this:

extensions [r csv]

globals [ 
  list-of-file-names 
  filename
]

to setup
  ca
  set filename ( word "landscape" n ".txt" )
  reset-ticks
end

With a widget like this:

enter image description here

And an experiment like this:

enter image description here

To get an output like this:

enter image description here

Which shows that for each of the runs, a different filename was generated.


推荐阅读