Loop Computations

Loop Computations

1.     Compare tables row by row to find the equals

Perform judgements by loop, adding a new member to an existing sequence each time.

【Example 1】Compare two files that have same number of rows to count the rows with same data. Below is part of the source data:

IDPredicted_YOriginal_Y
100.0123884643676080930.0
110.015198991239789880.0
130.00079202388850612480.0
190.00126563674681591020.0
210.0094605459974733790.0
230.0241767918716816640.0

【SPL script】

ABC
1=file("p_old.csv").import@ct()/ Read in the file first imported
2=file("p_new.csv").import@ct()/ Read in the second file imported
3for A1.len()=cmp(A1(A3),A2(A3))/ Compare the two files row by row by loop
4=@|B3/ Union each comparison result with B4’s value
5=B4.count(~==0)/ Count the rows having same data

   Below is A5’s result:

Value
11302

2.     Assign values by loop

Loop through members of a set to compute each and assign value to it.

【Example 2】According to the following sales table, give a  reward of sales amount’s 5% to each salesperson whose performance in 2014 rank the top 10%. Below is part of the source table:

OrderIDCustomerSellerIdOrderDateAmount
10400EASTC12014/01/013063.0
10401HANAR12014/01/013868.6
10402ERNSH82014/01/022713.5
10403ERNSH42014/01/031005.9
10404MAGAA22014/01/031675.0

【SPL script】

AB
1=connect("db").query("select * from sales")/ Connect to the data source to read in sales table
2=A1.select(year(OrderDate)==2014)/ Get data of 2014
3=A2.groups(SellerId;sum(Amount):Amount)/ Group A2 by seller and calculate the total sales amount in 2014
4=A3.sort@z(Amount).to(A3.len()*0.1)/ Sort A3 by sales amount in descending order and get records where the amount ranks top 10%
5=A4.run(Amount*=1.05)/ Use A.run() function to loop through A4’s selected records and give a reward of the sale’s amount’s 5% to each seller

   Below is A5’ s result:

SellerIdAmount
4150433.185
3127878.04
1102756.759
887965.346

3.     Complex inter-row computation

After data is grouped, summarize specific columns to get different aggregates while performing inter-row computations.

【Example 3】According to the user payment details table below, calculate the monthly sum payable in 2014 for each user. Below is part of the source table:

IDcustomIDnameamount_payabledue_dateamount_paidpay_date
112101C013CA128002014-02-21128002014-12-19
112102C013CA35002014-06-1535002014-12-15
112103C013CA26002015-03-2169002015-10-17

The target is to output the payable sum per month in the year of 2014. If no data exists for the current month, the payable sum will be the one in the previous month:

name123456789101112
CA1280012800128001280016300163001630016300163001630016300
ABC
1=file("Payment.txt").import@t().select(year(due_date)==2014)/ Import data of 2014 from the file
2=create(name,${12.().concat@c()})=A1.group(customID)/A2: Generate an empty table of 12 months. A3: Group A1 by customer ID
3for B2=12.(null)/ Generate null values for the 12 months
4>A3.run(B3(month(due_date))= amount_payable)/ Set the payable sum for the corresponding month
5>B3.run(~+=~[-1])/ Set null as payable sum of the previous month and calculate the cumulative sum month by month
6=A2.record(B2.name|B3)/ Insert records to the result table

【SPL script】

   Below is A2’s result:

name123456789101112
CA1280012800128001280016300163001630016300163001630016300

4.     Get the largest number of consecutively rising days

Count the frequency of continuous rising of a specific column value during the loop.

【Example 4】According to the SSE Composite Index records below, get the closing price’s largest number of consecutive rising days in 2019. Below is the part of the source table:

DateOpenCloseAmount
2019/12/313036.38583050.1242.27E11
2019/12/302998.16893040.02392.67E11
2019/12/273006.85173005.03552.58E11
2019/12/262981.24853007.35461.96E11
2019/12/252980.42762981.88051.9E11

【SPL script】

AB
1=file("000001.csv").import@ct()/ Import the source data file
2=A1.select(year(Date)==2019).sort(Date)/ Get records of 2019 and sort them by date
3=n=0,A2.max(if(Close>Close[-1],n+=1,n=0))/ Loop through closing prices to compare each one with the previous one and add 1 if the current price is higher, and then get the largest count

    Below is A3’s result:

Value
6

5.     Nested loop

Use loop functions in a nested way.

【Example 5】The hundred fowls problem: If a rooster is worth five coins, a hen three coins, and three chicks together are worth one coin, how many roosters, hens, and chicks totaling 100 can be bought for 100 coins?

【SPL script】

AB
1=to(100/5)/ Number of roosters that can be bought
2=to(100/3)/ Number of hens that can be bought
3=33.(~*3)/ Number of chicks that can be bought
4=create(Cock,Hen,Chick)/ Create an empty table to store the numbers of roosters, hens, and chicks
5>A1.run(A2.run(A3.run(if(A1.~+A2.~+A3.~==100 && A1.~*5+A2.~*3+A3.~/3==100,A4.insert(0,A1.~,A2.~,A3.~)))))/ Loop through the number of roosters, hens, and chicks respectively and insert the result records to A4’s table if the specific requirement is satisfied. The tilde sign is used to represent the current member

    Below is A4’s result:

CockHenChick
41878
81181
12484

6.     Call loop number during the loop

Query a certain file by loop to generate desired information during which the loop number is displayed.

【Example 6】Query file 2 to output specific information according to key words in file 1.

【SPL script】

AB
1=file("file1.txt").read@n()/ Read in file 1
2=file("file2.txt").read@n()/ Read in file 2
3=A1.conj(("Q"+string(#)+"."+~)|A2.select(pos(~,A1.~)).(~.words()(1)))/ Loop through file1’s strings to find them in each string file 2 and get the first word if it is matched. A2.select uses “~” to represent the current member of file 2; A1.~ is the current member of A1. Precede each query result with “Q + sequence number of the current member of A1”; the sequence number is obtained through “#”

Below is A3’s result:

Member
Q1. like parks
I
Shelly
Harry
Q2. went out
Shelly
Q3. go out
I
Ben
Harry

7.     Summarize data in skewness intervals starting from specific positions by loop

Calculate the average within skewness intervals starting from specific positions by loop.

【Example 7】According to the stock exchange table below, list the average closing price within 20 days for each transaction date during 1.1 – 1.10 in the year of 2020. Below is part of the source table:

DateOpenCloseAmount
2019/12/313036.38583050.1242.27E11
2019/12/302998.16893040.02392.67E11
2019/12/273006.85173005.03552.58E11
2019/12/262981.24853007.35461.96E11
2019/12/252980.42762981.88051.9E11

【SPL script】

AB
1=connect("db")/Connect to the data source
2=A1.query("select Date, Close from Stock where Code='600036'order by Date")/ Select records of the targeted stock and sort them by date
3=A2.pselect@a(Date>=date("2020/01/01") && Date<=date("2020/01/10"))/ Use A.pselect() function to get the sequence numbers of records from 1.1-1.10 in 2020
4=A2(A3).derive(A2.calc(A3(#),avg(Close[-19:0])):ma20)/ Use calc()function to calculate and return the average closing price within 20 days for each of the specified ten days. Close[-19:0] gets closing prices from 19 days ago to the current date

Below is A4’s result:

DateClosema20
2020/01/0238.8837.35
2020/01/0339.437.50
2020/01/0639.2437.64
2020/01/0739.1537.79
2020/01/0838.4137.90
2020/01/0938.938.03
2020/01/1039.0438.16

8.     Iterative accumulation

Perform iterative accumulation during the loop and then filtering according to the cumulative total.

【Example 8】According to the sales table below, count the days needed to bag 20 orders per month in the year of 2014. Below is part of the source table:

OrderIDCustomerSellerIdOrderDateAmount
10400EASTC12014/01/013063.0
10401HANAR12014/01/013868.6
10402ERNSH82014/01/022713.5
10403ERNSH42014/01/031005.9
10404MAGAA22014/01/031675.0

【SPL script】

AB
1=connect("db").query("select * from sales")/ Connect to the data source to read in the sales table
2=A1.select(year(OrderDate)==2014)/ Get records of 2014
3=A2.sort(OrderDate)/ Sort the selected records by order date
4=A3.select(seq(month(OrderDate))==20)/ Use seq() function to get sequence numbers of orders in each month, and then select the record whose sequence number is 20

Below is A4’s result:

MonthDay
120
220
320
418

9.     Post-grouping ranking

Get the rank in each group by loop.

【Example 9】According to the employee table below, get the rank of each employee’s salary in their department. Below is part of the source table:

IDNAMEDEPTSALARY
1RebeccaR&D7000
2AshleyFinance11000
3RachelSales9000
4EmilyHR7000
5AshleyR&D16000

【SPL script】

AB
1=connect("db") .query("select * from Employee order by DEPT, SALARY DESC")/ Connect to the data source, read in the employee table, and sort it by department and salary
2=A1.derive(rank(SALARY;DEPT):DeptRank)/ Use rank() function to number the ordered departments and salaries, and calculate department ranks

Below is A2’s result:

IDNAMEDEPTSALARYDeptRank
2AshleyFinance110001
32AndrewFinance110001
230HannahFinance100003
24ChloeFinance100003

10.   Post-grouping tight ranking

Get the tight ranks for specific fields in each group by loop.

【Example 10】According to the scores table below, get the ranks of all subject scores for the student whose ID is 8 in class one. Below is part of the source table:

CLASSSTUDENTIDSUBJECTSCORE
Class one1English84
Class one1Math77
Class one1PE69
Class one2English81
Class one2Math80

【SPL script】

AB
1=connect("db") .query("select * from SCORES where CLASS='Class one'order by SUBJECT, SCORE DESC")/ Connect to the data source, read in the scores table, and sort it by subject and score
2=A1.derive(ranki(SCORE;SUBJECT):Rank)/ Use ranki() function to number the ordered departments and salaries, and calculate the tight rank for each score
3=A2.select(STUDENTID==8)/ Get information of student whose ID is 8
4=create(${A3.(SUBJECT).concat@c()}).record(A3.(Rank))/ Join up tight ranks of scores of all subjects according to A3’ information

Below is A4’s result:

EnglishMathPE
10414

11.   Iterative sum

Calculate iterative sums by loop.

【Example 11】According to the SSE Composite Index records below, calculate the cumulative amount total for each transaction date in 2019. Below is part of the source table:

DateOpenCloseAmount
2019/12/313036.38583050.1242.27E11
2019/12/302998.16893040.02392.67E11
2019/12/273006.85173005.03552.58E11
2019/12/262981.24853007.35461.96E11
2019/12/252980.42762981.88051.9E11

【SPL script】

AB
1=file("000001.csv").import@ct()/ Import the source file
2=A1.select(year(Date)==2019).sort(Date)/ Select records of 2019 and sort them by date
3=A2.derive(cum(Amount):CUM)/ Use cum() function to calculate the cumulative amount total

Below is A3’s result:

DateOpenCloseAmountCUM
2019/01/022497.88052465.2919.759E109.759E10
2019/01/032461.78292464.36281.07E112.046E11
2019/01/042446.01932514.86821.39E113.436E11
2019/01/072528.69872533.08871.46E114.896E11
2019/01/082530.30012526.46221.23E116.126E11

12.   User-defined iterative computation

Users define the computing expression and the desired termination condition for the iteration computation performed within the loop.

【Example 12】According to the sales table below, get the date when the sales target of 150,000 is achieved for the first quarter. Below is part of the source table:

OrderIDCustomerSellerIdOrderDateAmount
10400EASTC12014/01/013063.0
10401HANAR12014/01/013868.6
10402ERNSH82014/01/022713.5
10403ERNSH42014/01/031005.9
10404MAGAA22014/01/031675.0

【SPL script】

AB
1=connect("db").query("select * from sales")/ Connect to the data source and read in the sales table
2=A1.select(year(OrderDate)==2014)/ Select data of 2014
3=A2.iterate((@+=Amount, ~~=OrderDate),0,@>150000)/ iterate() function performs the iterative computation with the initial value as 0 and returns the desired target date. Sum sales amounts to the current cell and until the total reaches 150,000.

Below is A3’s result:

Value
2014/03/25

There are more examples in SPL CookBook.

Leave a Reply