I am creating 33 variables which execute a db query and I know there must be a way to make it simpler then writing 33 lines of code manually. What I am doing right now is:
allrtd = c.execute("SELECT Amsterdam from rtdtimes")
allrtd1 = c.execute("SELECT Bucharest from rtdtimes")
allrtd2 = c.execute("SELECT Barcelona from rtdtimes")
allrtd3 = c.execute("SELECT Berlin from rtdtimes")
allrtd4 = c.execute("SELECT Bratislava from rtdtimes")
allrtd5 = c.execute("SELECT Budapest from rtdtimes")
allrtd6 = c.execute("SELECT Copenhagen from rtdtimes")
allrtd7 = c.execute("SELECT Dublin from rtdtimes")
allrtd8 = c.execute("SELECT Dusseldorf from rtdtimes")
allrtd9 = c.execute("SELECT Dubai from rtdtimes")
allrtd10 = c.execute("SELECT Florence from rtdtimes")
allrtd11 = c.execute("SELECT Frankfurt from rtdtimes")
allrtd12 = c.execute("SELECT Geneva from rtdtimes")
allrtd13 = c.execute("SELECT Hamburg from rtdtimes")
allrtd14 = c.execute("SELECT HongKong from rtdtimes")
allrtd15 = c.execute("SELECT Istanbul from rtdtimes")
allrtd16 = c.execute("SELECT LosAngeles from rtdtimes")
allrtd17 = c.execute("SELECT London from rtdtimes")
allrtd18 = c.execute("SELECT Madrid from rtdtimes")
allrtd19 = c.execute("SELECT Milan from rtdtimes")
allrtd20 = c.execute("SELECT Marseille from rtdtimes")
allrtd21 = c.execute("SELECT Moscow from rtdtimes")
allrtd22 = c.execute("SELECT Munich from rtdtimes")
allrtd23 = c.execute("SELECT NewYork from rtdtimes")
allrtd24 = c.execute("SELECT Paris from rtdtimes")
allrtd25 = c.execute("SELECT Prague from rtdtimes")
allrtd26 = c.execute("SELECT Rotterdam from rtdtimes")
allrtd27 = c.execute("SELECT Sofia from rtdtimes")
allrtd28 = c.execute("SELECT Stockholm from rtdtimes")
allrtd29 = c.execute("SELECT Venice from rtdtimes")
allrtd30 = c.execute("SELECT Vienna from rtdtimes")
allrtd31 = c.execute("SELECT Warsaw from rtdtimes")
allrtd32 = c.execute("SELECT Zurich from rtdtimes")
I have a list with all the city names already which is done like this:
city1 = ['Amsterdam', 'Bucharest', 'Barcelona', 'Berlin', 'Bratislava', 'Budapest',
'Copenhagen', 'Dublin', 'Dusseldorf', 'Dubai', 'Florence', 'Frankfurt',
'Geneva', 'Hamburg', 'HongKong', 'Istanbul', 'LosAngeles', 'London',
'Madrid', 'Milan', 'Marseille', 'Moscow', 'Munich', 'NewYork',
'Paris', 'Prague', 'Rotterdam', 'Sofia', 'Stockholm', 'Venice', 'Vienna',
'Warsaw', 'Zurich']
Also I am using Flask so I need to render this variable in the template so that I can use these variables in the html file.
Right now I am rendering it like this:
return render_template("Allresults.html", city1=city1, allrtd=allrtd,
allrtd1=allrtd1, allrtd2=allrtd2, allrtd3=allrtd3, allrtd4=allrtd4,
allrtd5=allrtd5, allrtd6=allrtd6, allrtd7=allrtd7, allrtd8=allrtd8,
allrtd9=allrtd9, allrtd10=allrtd10, allrtd11=allrtd11, allrtd12=allrtd12,
allrtd13=allrtd13, allrtd14=allrtd14, allrtd15=allrtd15, allrtd16=allrtd16,
allrtd17=allrtd17, allrtd18=allrtd18, allrtd19=allrtd19, allrtd20=allrtd20,
allrtd21=allrtd21, allrtd22=allrtd22, allrtd23=allrtd23, allrtd24=allrtd24,
allrtd25=allrtd25, allrtd26=allrtd26, allrtd27=allrtd27, allrtd28=allrtd28,
allrtd29=allrtd29, allrtd30=allrtd30, allrtd31=allrtd31, allrtd32=allrtd32)
I do not know how to use a dictionary to do exactly this as the duplicate question is very different to what I am doing.
You may benefit from a custom jinja2 filter here:
#app.template_filter('city_data')
def city_data(city_name):
return c.execute("SELECT {city} from rtdtimes".format(city=city_name))
#app.route('/')
def index():
return render_template("Allresults.html", cities=city1)
Then, in your Allresults.html template use:
{% for city in cities %}
{{ city|city_data }}
{% endfor %}
However, be very careful because you are leaving yourself open to SQL injection attacks if you ever allow a user to specify the city.
Related
I have to do a recursive function in pSQL to get the following query:
I have a table called tb_route with from_city and to_city
I have another column with the distance in km between different cities.
The table is builded recursively. I have to make a recursive CTE to show the route between two cities (i.e., from 'Santiago de compostela' to 'Saint Jean Pied de Port') showing the total km of the route and the cities where it goes through.
The output has to be something like this:
This is what I've tried:
WITH RECURSIVE cities AS (
SELECT *
FROM textil.tb_route
WHERE to_city_name = 'Santigo de Compostela'
UNION ALL
SELECT e.from_city, e.to_city, e.route, e.km
FROM textil.tb_route e
INNER JOIN cities tb_route ON tb_route.from_city_name = e.from_city
)
SELECT *
FROM cities;
And I had an error like:
ERROR: column e.from_city does not exist
LINE 8: ...JOIN cities tb_route ON tb_route.from_city_name = e.from_cit...
Table:
CREATE TABLE textil.tb_route
(
from_city_name CHARACTER VARYING(120) NOT NULL ,
to_city_name CHARACTER VARYING(120) NOT NULL ,
km_distance_num NUMERIC(5,2) NOT NULL ,
CONSTRAINT pk_route PRIMARY KEY (from_city_name, to_city_name)
);
Data:
INSERT INTO textil.tb_route VALUES
('Saint Jean Pied de Port','Roncesvalles',25.7),
('Somport','Jaca',30.5),
('Roncesvalles','Zubiri',21.5),
('Jaca','Arrés',25),
('Zubiri','Pamplona/Iruña',20.4),
('Arrés','Ruesta',28.7),
('Pamplona/Iruña','Puente la Reina/Gares',24),
('Ruesta','Sangüesa',21.8),
('Puente la Reina/Gares','Estella/Lizarra',22),
('Sangüesa','Monreal',27.25),
('Estella/Lizarra','Torres del Río',29),
('Monreal','Puente la Reina/Gares',31.1),
('Torres del Río','Logroño',20),
('Logroño','Nájera',29.6),
('Nájera','Santo Domingo de la Calzada',21),
('Santo Domingo de la Calzada','Belorado',22.7),
('Belorado','Agés',27.4),
('Agés','Burgos',23),
('Burgos','Hontanas',31.1),
('Hontanas','Boadilla del Camino',28.5),
('Boadilla del Camino','Carrión de los Condes',24.6),
('Carrión de los Condes','Terradillos de los Templarios',26.6),
('Terradillos de los Templarios','El Burgo Ranero',30.6),
('El Burgo Ranero','León',37.1),
('León','San Martín del Camino',25.9),
('San Martín del Camino','Astorga',24.2),
('Astorga','Foncebadón',25.9),
('Foncebadón','Ponferrada',27.3),
('Ponferrada','Villafranca del Bierzo',24.1),
('Villafranca del Bierzo','O Cebreiro',28.4),
('O Cebreiro','Triacastela',21.1),
('Triacastela','Sarria',18.3),
('Sarria','Portomarín',22.4),
('Portomarín','Palas de Rei',25),
('Palas de Rei','Arzúa',28.8),
('Arzúa','Pedrouzo',19.1),
('Pedrouzo','Santiago de Compostela',20),
('Bayona','Ustaritz',14.3),
('Ustaritz','Urdax',21.2),
('Urdax','Elizondo',18.8),
('Elizondo','Berroeta',9.7),
('Berroeta','Olagüe',20.4),
('Olagüe','Pamplona/Iruña',25),
('Irún','Hernani',26.6),
('Hernani','Tolosa',18.9),
('Tolosa','Zerain',33),
('Zerain','Salvatierra/Agurain',28),
('Salvatierra/Agurain','Vitoria/Gasteiz',27.4),
('Vitoria/Gasteiz','La Puebla de Arganzón',18.5),
('La Puebla de Arganzón','Haro',31),
('Haro','Santo Domingo de la Calzada',20),
('Bayona','Irún',33.8),
('Tolosa','Zegama',37.9),
('Zegama','Salvatierra/Agurain',20.1),
('La Puebla de Arganzón','Miranda del Ebro',22.3),
('Miranda del Ebro','Pancorbo',16.7),
('Pancorbo','Briviesca',23.4),
('Briviesca','Monasterio de Rodilla',19.8),
('Monasterio de Rodilla','Burgos',28.5);
```
Here I leave the solution I've get finally:
with recursive caminos(from_city_name, to_city_name, path, total_distance, terminar, ultima_ciudad) as (
-- Consulta base
select to_city_name
,'Saint Jean Pied de Port' -- Cambiar Destino
,concat(to_city_name, concat(' -> ', from_city_name))
,cast(km_distance_num as numeric(8,2))
,0 --No terminar
,from_city_name
from textil.tb_route
where to_city_name = 'Santiago de Compostela' -- Cambiar Origen
union all
-- Consulta recursiva
select caminos.from_city_name
,caminos.to_city_name
,concat(caminos.path, concat( ' -> ', tr.from_city_name))
,cast(caminos.total_distance + tr.km_distance_num as numeric(8,2))
,case when tr.from_city_name = caminos.to_city_name then 1 else 0 end
,tr.from_city_name
from caminos inner join textil.tb_route tr on tr.to_city_name = caminos.ultima_ciudad and caminos.terminar != 1
)
select from_city_name, to_city_name, path, total_distance
from caminos
where 1 = 1
and from_city_name = 'Santiago de Compostela' --Cambiar Origen
and ultima_ciudad = 'Saint Jean Pied de Port' -- Cambiar Destino
;
I understand your question as a graph-walking problem. As described in your questions, edges are directed (meaning that you can travel from from_city_name to to_city_name, but not the other way around).
Here is an approach using a recursive CTE. The idea is to start from a given city, and then follow all possible routes, while keeping track of the overall travel path in an arry. The recursion stops either when a circle is detected, or when the target city is reached. Then, the outer query filters on the successful paths (there may be none, one or several).
with recursive cte as (
select
from_city_name,
to_city_name,
km_distance_num,
array[from_city_name::text, to_city_name::text] path
from tb_route
where from_city_name = 'Saint Jean Pied de Port'
union all
select
r.from_city_name,
r.to_city_name,
c.km_distance_num + r.km_distance_num,
c.path || r.to_city_name::text
from tb_route r
inner join cte c on c.to_city_name = r.from_city_name
where
not r.to_city_name = any(c.path)
and c.from_city_name <> 'Santiago de Compostela'
)
select
path[1] from_city_name,
to_city_name,
km_distance_num,
array_to_string(path, ' > ') path
from cte
where to_city_name = 'Santiago de Compostela';
Demo on DB Fiddle:
from_city_name | to_city_name | km_distance_num | path
:---------------------- | :--------------------- | --------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Saint Jean Pied de Port | Santiago de Compostela | 775.3 | Saint Jean Pied de Port > Roncesvalles > Zubiri > Pamplona/Iruña > Puente la Reina/Gares > Estella/Lizarra > Torres del Río > Logroño > Nájera > Santo Domingo de la Calzada > Belorado > Agés > Burgos > Hontanas > Boadilla del Camino > Carrión de los Condes > Terradillos de los Templarios > El Burgo Ranero > León > San Martín del Camino > Astorga > Foncebadón > Ponferrada > Villafranca del Bierzo > O Cebreiro > Triacastela > Sarria > Portomarín > Palas de Rei > Arzúa > Pedrouzo > Santiago de Compostela
in perl, i want to insert year and parti from database 2 to database 1 if name from database 1 and name from database 2 is equal
database 1 database 2
----------------------------------- ----------------------------------
table truc table truc2
----------------------------------- ----------------------------------
id name year parti id name year parti
----------------------------------- ----------------------------------
1 Lapin 14 Lapin 2014 MODEM
118 Koala 33 Murène 1347 EELV
14 Murène 2 Ragondin 4218 SP
3 Ragondin 3 Koala 1512 CPNT
i want the result:
database 1
-----------------------------------
table truc
-----------------------------------
id name year parti
-----------------------------------
1 Lapin 2014 MODEM
118 Koala 1512 CPNT
14 Murène 1347 EELV
3 Ragondin 4218 SP
thanks for any response,
my code of perl and sql are here
Read from one database and update in the second one:
my $query2 = $db2->prepare('SELECT id, name, sex, year, parti FROM truc2');
my $query1 = $db1->prepare('UPDATE truc'
. ' SET year = ?, parti = ? WHERE name = ?');
$query2->execute;
while (my #row = $query2->fetchrow_array) {
$query1->execute($row[3], $row[4], $row[1]);
}
Tested with:
#!/usr/bin/perl
use warnings;
use strict;
use utf8;
use feature qw{ say };
use open IO => ':encoding(UTF-8)', ':std';
use DBI;
my $db1 = DBI->connect('dbi:SQLite:dbname=:memory:', "", "",
{ sqlite_unicode => 1 });
$db1->do('CREATE TABLE truc'
. ' (id INT, name TEXT, sex VARCHAR, year INT, parti TEXT)');
my $db2 = DBI->connect('dbi:SQLite:dbname=:memory:', "", "",
{ sqlite_unicode => 1 });
$db2->do('CREATE TABLE truc2'
. ' (id INT, name TEXT, sex VARCHAR, year INT, parti TEXT)');
my $insert1 = $db1->prepare('INSERT INTO truc (id, name, sex)'
. ' VALUES (?, ?, ?)');
$insert1->execute(#$_) for [ 1, 'Lapin', 'M'],
[118, 'Koala', 'F'],
[ 14, 'Murène', 'A'],
[ 3, 'Ragondin', 'F'];
my $insert2 = $db2->prepare('INSERT INTO truc2 (id, name, sex, year, parti)'
. ' VALUES (?, ?, ?, ?, ?)');
$insert2->execute(#$_) for [14, 'Lapin', 'A', 2014, 'MODEM'],
[33, 'Murène', 'F', 1347, 'EELV'],
[ 2, 'Ragondin', 'M', 4218, 'SP'],
[ 3, 'Koala', 'F', 1512, 'CPNT'];
my $query2 = $db2->prepare('SELECT id, name, sex, year, parti FROM truc2');
my $query1 = $db1->prepare('UPDATE truc'
. ' SET year = ?, parti = ? WHERE name = ?');
$query2->execute;
while (my #row = $query2->fetchrow_array) {
$query1->execute($row[3], $row[4], $row[1]);
}
my $verify = $db1->prepare('SELECT * from truc');
$verify->execute;
while (my #row = $verify->fetchrow_array) {
say "#row";
}
UPDATE database1.truc
JOIN database2.truc2 ON database1.truc.name = database2.truc2.name
SET database1.truc.year = database2.truc2.year
database1.truc.parti = database2.truc2.parti;
No binding, no copying data into arrays, no loss of id, etc.
Trying to compare df1 and df2 for 'Cntr No' AND either the value in any of the column of df2 ['Labour Cost', Material Cost', 'Amount in Estimate Currency'] must be matched with df1's Total.
For example df1 OOLU 3868088 is matched with df2 OOLU 3868088 AND the Total value of df1 "28" is matched with df2's "Labour Cost" value of '28'.
df:
df1 = pd.DataFrame({'Cntr No': ['OOLU 3868088','OOLU 3868088','OOLU 3868088','TRIU 0625840','TRIU 0625840','TRIU 0625840','TRIU 1234567','OOLU 6232016','OOLU 0981231','OOLU 1212444'],
'Total': [12,28,48,119,82.5,11.0,18.0,11.0,13.0,10.0]})
df2 = pd.DataFrame({'Cntr No': ['OOLU 3868088','OOLU 3868088','OOLU 3868088','TRIU 0625840','TRIU 0625840','TRIU 0625840','TRIU 1234567'],
'Labour Cost': [0.0,0.0,28.0,0.0,54.0,0.0,0.0],
'Material Cost':[0.00,12.0,58.91,82.5,54.0,0.0,16.0],
'Amount in Estimate Currency':[48.00,12.00,87.81,82.5,119.0,12.0,16.0]})
Expected output:
Cntr No Total Tally_with_df2
0 OOLU 3868088 12.0 Yes
1 OOLU 3868088 28.0 Yes
2 OOLU 3868088 48.0 Yes
3 TRIU 0625840 119.0 Yes
4 TRIU 0625840 82.5 Yes
5 TRIU 0625840 11.0 No
6 TRIU 1234567 18.0 No
Used code: this is the below code I tried on but doesn't able to achieve my requirements
cols = ['Labour Cost', 'Material Cost', 'Amount in Estimate Currency']
d = {k: set(v.values()) for k, v in \
df_co.set_index('Cntr No')[cols].to_dict(orient='index').items()}
df['Tally'] = [j in d.get(i, set()) for i, j in zip(df['Cntr No'], df['Total'])]
df['Tally'] = df['Tally'].map({True: 'Yes', False: 'No'})
df1:
Cntr No object
Serviced By object
Location object
WO No object
WASH - CHEMICAL float64
PTI - CHILL float64
WASHING CONTAINER AGENT float64
WASH - CHEMICAL AGENT float64
WASHING CONTAINER -AGENT float64
BUNDLING/UNBUNDLING OF FR float64
PTI - AUTO float64
PTI float64
Struct Repair - Labour float64
Struct Repair - Material float64
Machy Repair - Labour float64
Total float64
Vendor object
Sz object
Ty object
CO object
WO Date object
WO ID object
df2:
Cntr No object
Equipment Size/type Group Code object
Labour Cost float64
Material Cost float64
Amount in Estimate Currency float64
Remarks object
IIUC, we can create a groupby data from df2 for every unique Cntr No.
## this is grouped data
to_remove = df2.select_dtypes(['object']).columns.values.tolist()
df3 = (df2
.groupby('Cntr No')
.apply(lambda df: set(np.concatenate(df.loc[:, df.columns.difference(to_remove)].values))))
## df3 looks like this - using set for faster speed
print(df3)
Cntr No
OOLU 3868088 {0.0, 12.0, 48.0, 87.81, 58.91, 28.0}
TRIU 0625840 {0.0, 12.0, 82.5, 54.0, 119.0}
TRIU 1234567 {16.0, 0.0}
## this function ensures all cases are handles
def get_value(x, data):
if x['Cntr No'] not in data.index:
return 'Not Found'
else:
if x['Total'] in data[x['Cntr No']]:
return 'Yes'
else:
return 'No'
## next we do a simple look-up
df1['Tally_with_df2'] = df1.apply(lambda x: get_value(x, df3), axis=1)
print(df1)
Cntr No Total Tally_with_df2
0 OOLU 3868088 12.0 Yes
1 OOLU 3868088 28.0 Yes
2 OOLU 3868088 48.0 Yes
3 TRIU 0625840 119.0 Yes
4 TRIU 0625840 82.5 Yes
5 TRIU 0625840 11.0 No
6 TRIU 1234567 18.0 No
I am finding myself a bit stuck,
I want to show flows between regions for trafficked species via a chord diagram on circlize, but am unable to work out how to plot when column 1 and 2 represent the "connection", column 3 is the "factor" of interest and column 4 are the values.
I have included a sample of data below (yes I am aware indonesia is a region), as you can see each species is not unique to a particular region. I would like to produce a plot similar to the one included below but replace the "countries" with "species" for each region. Is this possible to do?
import_region export_region species flow
North America Europe Acanthosaura armata 0.0104
Southeast Asia Europe Acanthosaura armata 0.0022
Indonesia Europe Acanthosaura armata 0.1971
Indonesia Europe Acrochordus granulatus 0.7846
Southeast Asia Europe Acrochordus granulatus 0.1101
Indonesia Europe Acrochordus javanicus 2.00E-04
Southeast Asia Europe Acrochordus javanicus 0.0015
Indonesia North America Acrochordus javanicus 0.0024
East Asia Europe Acrochordus javanicus 0.0028
Indonesia Europe Ahaetulla prasina 4.00E-04
Southeast Asia Europe Ahaetulla prasina 4.00E-04
Southeast Asia East Asia Amyda cartilaginea 0.0027
Indonesia East Asia Amyda cartilaginea 5.00E-04
Indonesia Europe Amyda cartilaginea 0.004
Indonesia Southeast Asia Amyda cartilaginea 0.0334
Europe North America Amyda cartilaginea 4.00E-04
Indonesia North America Amyda cartilaginea 0.1291
Southeast Asia Southeast Asia Amyda cartilaginea 0.0283
Indonesia West Asia Amyda cartilaginea 0.7614
South Asia Europe Amyda cartilaginea 2.8484
Australasia Europe Apodora papuana 0.0368
Indonesia North America Apodora papuana 0.324
Indonesia Europe Apodora papuana 0.0691
Europe Europe Apodora papuana 0.0106
Indonesia East Asia Apodora papuana 0.0129
Europe North America Apodora papuana 0.0034
East Asia East Asia Apodora papuana 2.00E-04
Indonesia Southeast Asia Apodora papuana 0.0045
East Asia North America Apodora papuans 0.0042
example of diagram similar to what I would like, please click link below:
chord diagram
In circlize package, the ChordDiagram() function only allows a "from" column, a "to" column and a optional "value" column. However, in your case, actually we can make some transformation for the original data frame to modify it into a three-column data frame.
In you example, you want to distinguish e.g. Acanthosaura_armata in North America from Acanthosaura_armata in Europe, one solution is to merge region names and species names such as Acanthosaura_armata|North_America to form a unique identifier. Next I will demonstrate how to visualize this dataset by circlize package.
Read in the data. Note I replaced space with underscores.
df = read.table(textConnection(
"import_region export_region species flow
North_America Europe Acanthosaura_armata 0.0104
Southeast_Asia Europe Acanthosaura_armata 0.0022
Indonesia Europe Acanthosaura_armata 0.1971
Indonesia Europe Acrochordus_granulatus 0.7846
Southeast_Asia Europe Acrochordus_granulatus 0.1101
Indonesia Europe Acrochordus_javanicus 2.00E-04
Southeast_Asia Europe Acrochordus_javanicus 0.0015
Indonesia North_America Acrochordus_javanicus 0.0024
East_Asia Europe Acrochordus_javanicus 0.0028
Indonesia Europe Ahaetulla_prasina 4.00E-04
Southeast_Asia Europe Ahaetulla_prasina 4.00E-04
Southeast_Asia East_Asia Amyda_cartilaginea 0.0027
Indonesia East_Asia Amyda_cartilaginea 5.00E-04
Indonesia Europe Amyda_cartilaginea 0.004
Indonesia Southeast_Asia Amyda_cartilaginea 0.0334
Europe North_America Amyda_cartilaginea 4.00E-04
Indonesia North_America Amyda_cartilaginea 0.1291
Southeast_Asia Southeast_Asia Amyda_cartilaginea 0.0283
Indonesia West_Asia Amyda_cartilaginea 0.7614
South_Asia Europe Amyda_cartilaginea 2.8484
Australasia Europe Apodora_papuana 0.0368
Indonesia North_America Apodora_papuana 0.324
Indonesia Europe Apodora_papuana 0.0691
Europe Europe Apodora_papuana 0.0106
Indonesia East_Asia Apodora_papuana 0.0129
Europe North_America Apodora_papuana 0.0034
East_Asia East_Asia Apodora_papuana 2.00E-04
Indonesia Southeast_Asia Apodora_papuana 0.0045
East_Asia North_America Apodora_papuans 0.0042"),
header = TRUE, stringsAsFactors = FALSE)
Also, I removed some rows which have very tiny values.
df = df[df[[4]] > 0.01, ]
Assign colors for species and regions.
library(circlize)
library(RColorBrewer)
all_species = unique(df[[3]])
color_species = structure(brewer.pal(length(all_species), "Set1"), names = all_species)
all_regions = unique(c(df[[1]], df[[2]]))
color_regions = structure(brewer.pal(length(all_regions), "Set2"), names = all_regions)
Group by species
First I will demonstrate how to group the chord diagram by species.
As mentioned before, we use species|region as unique identifier.
df2 = data.frame(from = paste(df[[3]], df[[1]], sep = "|"),
to = paste(df[[3]], df[[2]], sep = "|"),
value = df[[4]], stringsAsFactors = FALSE)
Next we adjust the order of all sectors to first order by species, then by regions.
combined = unique(data.frame(regions = c(df[[1]], df[[2]]),
species = c(df[[3]], df[[3]]), stringsAsFactors = FALSE))
combined = combined[order(combined$species, combined$regions), ]
order = paste(combined$species, combined$regions, sep = "|")
We want the color of the links to be the same as the color of regoins
grid.col = structure(color_regions[combined$regions], names = order)
Since the chord diagram is grouped by species, gaps between species should be larger than inside each species.
gap = rep(1, length(order))
gap[which(!duplicated(combined$species, fromLast = TRUE))] = 5
With all settings ready, we now can make the chord diagram:
In following code, we set preAllocateTracks so that circular lines which represents species will be added afterwards.
circos.par(gap.degree = gap)
chordDiagram(df2, order = order, annotationTrack = c("grid", "axis"),
grid.col = grid.col, directional = TRUE,
preAllocateTracks = list(
track.height = 0.04,
track.margin = c(0.05, 0)
)
)
Circular lines are added to represent species:
for(species in unique(combined$species)) {
l = combined$species == species
sn = paste(combined$species[l], combined$regions[l], sep = "|")
highlight.sector(sn, track.index = 1, col = color_species[species],
text = species, niceFacing = TRUE)
}
circos.clear()
And the legends for regions and species:
legend("bottomleft", pch = 15, col = color_regions,
legend = names(color_regions), cex = 0.6)
legend("bottomright", pch = 15, col = color_species,
legend = names(color_species), cex = 0.6)
The plot looks like this:
Group by regions
The code is similar that I will not explain it but just attach the code in the post. The plot looks like this:
## group by regions
df2 = data.frame(from = paste(df[[1]], df[[3]], sep = "|"),
to = paste(df[[2]], df[[3]], sep = "|"),
value = df[[4]], stringsAsFactors = FALSE)
combined = unique(data.frame(regions = c(df[[1]], df[[2]]),
species = c(df[[3]], df[[3]]), stringsAsFactors = FALSE))
combined = combined[order(combined$regions, combined$species), ]
order = paste(combined$regions, combined$species, sep = "|")
grid.col = structure(color_species[combined$species], names = order)
gap = rep(1, length(order))
gap[which(!duplicated(combined$species, fromLast = TRUE))] = 5
circos.par(gap.degree = gap)
chordDiagram(df2, order = order, annotationTrack = c("grid", "axis"),
grid.col = grid.col, directional = TRUE,
preAllocateTracks = list(
track.height = 0.04,
track.margin = c(0.05, 0)
)
)
for(region in unique(combined$regions)) {
l = combined$regions == region
sn = paste(combined$regions[l], combined$species[l], sep = "|")
highlight.sector(sn, track.index = 1, col = color_regions[region],
text = region, niceFacing = TRUE)
}
circos.clear()
legend("bottomleft", pch = 15, col = color_regions,
legend = names(color_regions), cex = 0.6)
legend("bottomright", pch = 15, col = color_species, l
egend = names(color_species), cex = 0.6)
I got a problem on MS SQL :
I'm using a CASE with many statements in my view, like this :
select
e.[Nom d'annuaire],
e.[Prénom annuaire],
f.[Nom d'annuaire en UTF-8] AS login,
e.Usagers as [Numéro interne],
d.[Numéro externe],
s.[Préfixe No abr direct],
v.fonction,
CASE
WHEN v.lib_delegation = 'Service informatique' THEN 'Euralille'
WHEN v.delegation = 'test_national' THEN 'Maillot'
WHEN v.delegation = 'test_tpe' THEN 'Maillot'
WHEN v.delegation = 'test_paris-idf' THEN 'Maillot'
WHEN v.delegation = 'test_grands-comptes' THEN 'Maillot'
WHEN v.delegation = 'cotestrm' THEN 'Marcq en baroeul'
WHEN v.delegation = 'test_sud-ouest' THEN 'Bruges'
WHEN v.delegation = 'test_normandie' THEN 'Caen'
WHEN v.delegation = 'test_bourgogne' THEN 'Dijon'
WHEN v.delegation = 'test_ouest' THEN 'Ouest'
WHEN v.lib_delegation = 'Centre Limousin' THEN 'Tours'
WHEN v.delegation = 'test_est' THEN 'Nancy'
WHEN v.delegation = 'test_mediterranee' THEN 'Aix'
WHEN v.delegation = 'test_rhone-alpes' THEN 'Lyon'
ELSE v.delegation
END AS Délégation,
v.lib_delegation
from ale e
INNER JOIN ale f
on e.Usagers = f.Usagers AND f.[No alias] = 1 and e.[No Alias] = 0
INNER JOIN Delegation d
on f.Usagers = d.[No annuaire]
INNER JOIN V_users v
on v.LOGIN = f.[Nom d'annuaire en UTF-8]
LEFT OUTER JOIN svi s
on e.Usagers = s.[No d'appel]
order by e.Usagers
As you can see, my CASE statements aren't nasted, because I'm using WHEN... THEN ... syntax and then I simply put ELSE ... END statement.
However, when I try to filter my output using for example filter :
WHERE [Délégation] = 'Euralille'
I just get 2 errors :
Msg 8180, Level 16, State 1, Line 1
Msg 125, Level 15, State 4, Line 1
Explanation of the Error Numbers:
Msg 8180 = Statement(s) could not be prepared.
Msg 125 = Case expressions may only be nested to level %d.
(Sorry for the poor french traduction)
I've been looking for the answer on MS SQL Website, and on StackOverflow but the problem is always that the CASE statements are nasted. But to me, I'm not in this situation...
Thanks in advance, I'm quite a beginner in this world.
Did you filter like this? Note that I put all of your query into a subquery and then applied the where clause afterwards:
select * from
(select
e.[Nom d'annuaire],
e.[Prénom annuaire],
f.[Nom d'annuaire en UTF-8] AS login,
e.Usagers as [Numéro interne],
d.[Numéro externe],
s.[Préfixe No abr direct],
v.fonction,
CASE
WHEN v.lib_delegation = 'Service informatique' THEN 'Euralille'
WHEN v.delegation = 'test_national' THEN 'Maillot'
WHEN v.delegation = 'test_tpe' THEN 'Maillot'
WHEN v.delegation = 'test_paris-idf' THEN 'Maillot'
WHEN v.delegation = 'test_grands-comptes' THEN 'Maillot'
WHEN v.delegation = 'cotestrm' THEN 'Marcq en baroeul'
WHEN v.delegation = 'test_sud-ouest' THEN 'Bruges'
WHEN v.delegation = 'test_normandie' THEN 'Caen'
WHEN v.delegation = 'test_bourgogne' THEN 'Dijon'
WHEN v.delegation = 'test_ouest' THEN 'Ouest'
WHEN v.lib_delegation = 'Centre Limousin' THEN 'Tours'
WHEN v.delegation = 'test_est' THEN 'Nancy'
WHEN v.delegation = 'test_mediterranee' THEN 'Aix'
WHEN v.delegation = 'test_rhone-alpes' THEN 'Lyon'
ELSE v.delegation
END AS Délégation,
v.lib_delegation
from ale e
INNER JOIN ale f
on e.Usagers = f.Usagers AND f.[No alias] = 1 and e.[No Alias] = 0
INNER JOIN Delegation d
on f.Usagers = d.[No annuaire]
INNER JOIN V_users v
on v.LOGIN = f.[Nom d'annuaire en UTF-8]
LEFT OUTER JOIN svi s
on e.Usagers = s.[No d'appel]
order by e.Usagers) as subTotalQuery
WHERE [Délégation] = 'Euralille'