Considering the following MATLAB structure
report.SCENARIO.CAT.GAS = YEARS (n*n double)
I would like to build a table with the field CAT as a row and the field GAS as a column and then fill the corresponding cells with the YEARS. I am currently proceeding as follows:
function loopover(myStruct)
scenario = fiedlnames(myStruct)
for scenarioidx = 1:length(scenario)
scenarioname = scenario{scenarioidx};
category = fieldnames(myStruct.(scenarioname))
row = category
for categoryidx = 1:length(category)
categoryname = category{categoryidx};
gas = fieldnames(myStruct.(scenarioname).(categoryname))
col = gas
end
for gasidx = 1:length(gas)
gasname = gas{gasidx}
allData(2:end) = gas #gas name starting at the second column
allData(2:end,2) = category #category name starting at the second line
allData(row,col) = myStruct.(scenarioname).(categoryname).(gasname) #filling the cells with corresponding years
end
end
When running this small script I just get an error message
Undefined function or variable "allData"
Does anyone know why? Or maybe better, how to proceed to build such a table?
P.S.: I am using MATLAB R2012, therefore I don´t have access to the struct2table or cell2table functions!
Related
See how the attribute table should be if the algorithm worksHow can I loop through vector data with an attribute table so that I create a new field by appending values from an already existing field in the vector data? So the logic I want to have is this:
I want that when I run the script, a search for the expression “Out” is done in the field index with the name “fa_to”. If found, the corresponding row value in the ‘fa_id is then inserted into the newly created field named ‘Bury_ID. It does this until it exhausts the entire row value for ‘fa_to.
My Code:
fn = ‘C:/PLUGINS1/p3/now3.shp’
tile_layer_used = iface.addVectorLayer(fn, ”, ‘ogr’)
fc = tile_layer_used.featureCount()
fa_to = tile_layer_used.fields().indexFromName(‘Tile_TO’) #field has all integers and a row named ‘Out’
fa_id = tile_layer_used.fields().indexFromName(‘Tile_ID’) #field id with numbers 1 to 50
# fa_to Tally with the fa_id
my_field_name = ‘Bury_ID’
tileorder = {}
with edit(tile_layer_used):
tile_layer_used.addAttribute(QgsField(my_field_name, QVariant.String, len=5, prec=0))
tile_layer_used.updateFields()
for f in tile_layer_used.getFeatures():
if fa_to == “Out”:
tileorder = fa_id
else:
tileorder = fa_id
f[my_field_name] = tileorder
tile_layer_used.updateFeature(f)
my output creates the new field named ‘Bury_ID’ but only has a single number all through instead of the corresponding field ids from ‘fa_id’.
Hello i am trying to write an existing xlsx file using phpspreadsheet with setActiveSheetIndexByName(sheetname) and setcellvalue with reference and value, but it updates only the last record. spent more than 12 hours on this.
i tried foreach instead of while and used a counter to increment, but none worked.
<?php
include_once('db.php');
$prospect = $_REQUEST['prospect'];
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
$sql1 = mysqli_query($db,"select filename,sheetname, row, responsecol,compliancecol,response, compliance from spreadsheet where `prospect`='$prospect' and response <>'' order by row");
//$row=1;
while($row1 = mysqli_fetch_assoc($sql1))
{
$filename= $row1['filename']; //test.xlsx
$sheetname= $row1['sheetname']; // mysheet
$responsecol= $row1['responsecol'].$row1['row']; //D1
$response= $row1['response']; //response
$compliancecol= $row1['compliancecol'].$row1['row']; //C1
$compliance= $row1['compliance']; //compliance
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($filename);
$spreadsheet->setActiveSheetIndexByName($sheetname)
->setCellValue($compliancecol,$compliance)
->setCellValue($responsecol,$response);
//$row++;
}
$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save("newfile.xlsx");
exit;
?>
i wish each of the row from mysqli result updates each reference cell with value.
The easys way is to set a Limit of 1 to your MySQL query. That takes only one value from your data. If you will the last you should sort DESC.
$sql1 = mysqli_query($db,"select filename,sheetname, row, responsecol,compliancecol,response, compliance from spreadsheet where `prospect`='$prospect' and response <>'' order by row DESC LIMIT 1");
Currently my code have simple tables containing the data needed for each object like this:
infantry = {class = "army", type = "human", power = 2}
cavalry = {class = "panzer", type = "motorized", power = 12}
battleship = {class = "navy", type = "motorized", power = 256}
I use the tables names as identifiers in various functions to have their values processed one by one as a function that is simply called to have access to the values.
Now I want to have this data stored in a spreadsheet (csv file) instead that looks something like this:
Name class type power
Infantry army human 2
Cavalry panzer motorized 12
Battleship navy motorized 256
The spreadsheet will not have more than 50 lines and I want to be able to increase columns in the future.
Tried a couple approaches from similar situation I found here but due to lacking skills I failed to access any values from the nested table. I think this is because I don't fully understand how the tables structure are after reading each line from the csv file to the table and therefore fail to print any values at all.
If there is a way to get the name,class,type,power from the table and use that line just as my old simple tables, I would appreciate having a educational example presented. Another approach could be to declare new tables from the csv that behaves exactly like my old simple tables, line by line from the csv file. I don't know if this is doable.
Using Lua 5.1
You can read the csv file in as a string . i will use a multi line string here to represent the csv.
gmatch with pattern [^\n]+ will return each row of the csv.
gmatch with pattern [^,]+ will return the value of each column from our given row.
if more rows or columns are added or if the columns are moved around we will still reliably convert then information as long as the first row has the header information.
The only column that can not move is the first one the Name column if that is moved it will change the key used to store the row in to the table.
Using gmatch and 2 patterns, [^,]+ and [^\n]+, you can separate the string into each row and column of the csv. Comments in the following code:
local csv = [[
Name,class,type,power
Infantry,army,human,2
Cavalry,panzer,motorized,12
Battleship,navy,motorized,256
]]
local items = {} -- Store our values here
local headers = {} --
local first = true
for line in csv:gmatch("[^\n]+") do
if first then -- this is to handle the first line and capture our headers.
local count = 1
for header in line:gmatch("[^,]+") do
headers[count] = header
count = count + 1
end
first = false -- set first to false to switch off the header block
else
local name
local i = 2 -- We start at 2 because we wont be increment for the header
for field in line:gmatch("[^,]+") do
name = name or field -- check if we know the name of our row
if items[name] then -- if the name is already in the items table then this is a field
items[name][headers[i]] = field -- assign our value at the header in the table with the given name.
i = i + 1
else -- if the name is not in the table we create a new index for it
items[name] = {}
end
end
end
end
Here is how you can load a csv using the I/O library:
-- Example of how to load the csv.
path = "some\\path\\to\\file.csv"
local f = assert(io.open(path))
local csv = f:read("*all")
f:close()
Alternative you can use io.lines(path) which would take the place of csv:gmatch("[^\n]+") in the for loop sections as well.
Here is an example of using the resulting table:
-- print table out
print("items = {")
for name, item in pairs(items) do
print(" " .. name .. " = { ")
for field, value in pairs(item) do
print(" " .. field .. " = ".. value .. ",")
end
print(" },")
end
print("}")
The output:
items = {
Infantry = {
type = human,
class = army,
power = 2,
},
Battleship = {
type = motorized,
class = navy,
power = 256,
},
Cavalry = {
type = motorized,
class = panzer,
power = 12,
},
}
I have a cell array that I call "Table", as in the code below (but my array has more lines). Column 1 contains dates in string format. I want to add an additional column that contains the dates in datetime format. I did the following, which works, but it is VERY slow. What are the alternatives?
% Table that I have:
Table{1,1} = 'Stringdate';
Table{2,1} = '01.01.1999';
Table{3,1} = '02.01.1999';
Table{4,1} = '03.01.1999';
Table{5,1} = '04.01.1999';
% What I want to add:
Table{1, size(Table,2)+1} = 'Datetime';
for index = 2:length(Table)
Table{index, size(Table,2)} = datetime(Table{index, 1});
end
You can apply datetime to all of them in one-go and use just num2cell and indexing to achieve the same result as that of your loop.
Table(2:end,2) = num2cell(datetime(Table(2:end,1)));
%You might need to specify the InputFormat as well i.e.
%Table(2:end,2) = num2cell(datetime(Table(2:end,1),'InputFormat','dd.MM.yyyy'));
I would like to build a table in "ascii" format, using the "struct2table" function. When printed into a cell my structure as the following characteristics:
report.COUNTRY.SOURCE.SCENARIO.CATEGORY.ENTITY = YEAR YEAR
Therefore in order to use the "struct2table" function I wrote a script that loops over field names as follow:
function comboloop = loopover(myStruct)
country=fieldnames(myStruct);
for countryidx=1:length(country)
countryname=country{countryidx};
source=fieldnames(myStruct.(countryname))
for sourceidx=1:length(source)
sourcename=source{sourceidx};
scenario=fieldnames(myStruct.(countryname).(sourcename))
for scenarioidx=1:length(scenario)
scenarioname=scenario{scenarioidx};
category=fieldnames(myStruct.(countryname).(sourcename).(scenarioname))
for categoryidx=1:length(category)
categoryname=category{categoryidx};
struct2table(myStruct.(countryname).(sourcename).(scenarioname).(categoryname))
end
end
end
end
end
Then, I have two problem with the output:
The output is printed directly on the command window, therefore how can I get an output as a table (ascii) in the workspace or outside matlab?
When I use table=struct2table(myStruct.(countryname).(sourcename).(scenarioname).(categoryname)) I get the error message "too many output arguments".
How can I append the results of the line category=fieldnames(myStruct.(countryname).(sourcename).(scenarioname))as a row header of the created output?
Any kind of helps or hints is greatly appreciated since I am struggling quiet a lot for this task!
As an example:
country = HUN
countryname = HUN
source = CRF2014
sourcename = CRF2014
scenario = BASEYEAR
scenarioname = BASEYEAR
category = CAT0 CAT1 CAT2 CAT3
categoryname = CAT0 CAT1 CAT2 CAT3
when running the struct2table, for each categoryname I have several gas entities as a column header (CO2, CH4, N2,...) and below I have the attached years (1990, 1991, 1992,...)