Goal Docs
::
working with tables.
We show below an html highlighted version of the Goal file
found at
examples/dplyr.goal
in the repos.
/ We translate to Goal most examples (as of 2024-09-12) from:
/ https://dplyr.tidyverse.org/articles/dplyr.html
/ We put in a comment the dplyr version for each example (uncomment to print
/ it before the table). We try to write solutions close to dplyr's ones.
(env"GOALLIB")or"GOALLIB"env"../lib"
import"fmt" / assuming GOALLIB contains now goal's lib directory
/ pp[t] pretty prints dict as table, assuming string keys, limiting results to
/ at most 5 rows and 8 columns, using "%.1f" to format floats.
pp:fmt.tbl[;5;8;"%.1f"]
/ Using the csv file adapted from https://swapi.dev for dplyr's examples.
t:{(*'x)!1_'x}@csv 'read"data/starwars.csv" / read csv file into t
t:+sub["_";""]@+t / clean non-identifier column names
t:@[t;!"height mass birthyear";"n"$] / parse numeric columns
/ dim(starwars)
say(nr:#*t;#t) / dimensions
/ 87 14
/ starwars
pp t
/ === Table 87x14 ===
/ name height mass haircolor skincolor eyecolor birthyear sex
/ ---------------- ------ ----- --------- ------------- -------- --------- --------
/ "Luke Skywalker" 172.0 77.0 "blond" "fair" "blue" 19.0 "male"
/ "C-3PO" 167.0 75.0 "NA" "gold" "yellow" 112.0 "none"
/ "R2-D2" 96.0 32.0 "NA" "white, blue" "red" 33.0 "none"
/ "Darth Vader" 202.0 136.0 "none" "white" "yellow" 41.9 "male"
/ "Leia Organa" 150.0 49.0 "brown" "light" "brown" 19.0 "female"
/ starwars %>% filter(skin_color == "light", eye_color == "brown")
pp(1;..skincolor="light";..eyecolor="brown")#t
/ === Table 7x14 ===
/ name height mass haircolor skincolor eyecolor birthyear sex
/ ------------------- ------ ---- --------- --------- -------- --------- --------
/ "Leia Organa" 150.0 49.0 "brown" "light" "brown" 19.0 "female"
/ "Biggs Darklighter" 183.0 84.0 "black" "light" "brown" 24.0 "male"
/ "Padmé Amidala" 185.0 45.0 "brown" "light" "brown" 46.0 "female"
/ "Cordé" 157.0 NaN "brown" "light" "brown" NaN "NA"
/ "Dormé" 165.0 NaN "brown" "light" "brown" NaN "female"
/ starwars %>% arrange(height, mass)
rmnan:{(0;..|/nan'x@!p.x)^y} / removes rows with NaNs in columns x from table y
pp (..x@<height)(..x@<mass)rmnan["mass height";t]
/ === Table 59x14 ===
/ name height mass haircolor skincolor eyecolor birthyear sex
/ ----------------------- ------ ---- --------- ------------- --------- --------- ------
/ "Yoda" 66.0 17.0 "white" "green" "brown" 896.0 "male"
/ "Ratts Tyerel" 79.0 15.0 "none" "grey, blue" "unknown" NaN "male"
/ "Wicket Systri Warrick" 88.0 20.0 "brown" "brown" "brown" 8.0 "male"
/ "Dud Bolt" 94.0 45.0 "none" "blue, grey" "yellow" NaN "male"
/ "R2-D2" 96.0 32.0 "NA" "white, blue" "red" 33.0 "none"
/ starwars %>% arrange(desc(height))
pp (..x@>height)rmnan["height";t]
/ === Table 81x14 ===
/ name height mass haircolor skincolor eyecolor birthyear sex
/ -------------- ------ ----- --------- --------- -------- --------- ------
/ "Yarael Poof" 264.0 NaN "none" "white" "yellow" NaN "male"
/ "Tarfful" 234.0 136.0 "brown" "brown" "blue" NaN "male"
/ "Lama Su" 229.0 88.0 "none" "grey" "black" NaN "male"
/ "Chewbacca" 228.0 112.0 "brown" "unknown" "blue" 200.0 "male"
/ "Roos Tarpals" 224.0 82.0 "none" "grey" "orange" NaN "male"
/ starwars %>% slice(5:10)
pp t[4+!5]
/ === Table 5x14 ===
/ name height mass haircolor skincolor eyecolor birthyear sex
/ -------------------- ------ ----- ------------- ------------ -------- --------- --------
/ "Leia Organa" 150.0 49.0 "brown" "light" "brown" 19.0 "female"
/ "Owen Lars" 178.0 120.0 "brown, grey" "light" "blue" 52.0 "male"
/ "Beru Whitesun Lars" 165.0 75.0 "brown" "light" "blue" 47.0 "female"
/ "R5-D4" 97.0 32.0 "NA" "white, red" "red" NaN "none"
/ "Biggs Darklighter" 183.0 84.0 "black" "light" "brown" 24.0 "male"
/ starwars %>% slice_head(n = 3)
pp t[!3]
/ === Table 3x14 ===
/ name height mass haircolor skincolor eyecolor birthyear sex
/ ---------------- ------ ---- --------- ------------- -------- --------- ------
/ "Luke Skywalker" 172.0 77.0 "blond" "fair" "blue" 19.0 "male"
/ "C-3PO" 167.0 75.0 "NA" "gold" "yellow" 112.0 "none"
/ "R2-D2" 96.0 32.0 "NA" "white, blue" "red" 33.0 "none"
/ starwars %>% slice_sample(n = 5)
pp t[5?nr]
/ === Table 5x14 ===
/ name height mass haircolor skincolor eyecolor birthyear sex
/ ------------------ ------ ---- --------- --------------- --------- --------- --------
/ "Gasgano" 122.0 NaN "none" "white, blue" "black" NaN "male"
/ "Nute Gunray" 191.0 90.0 "none" "mottled green" "red" NaN "male"
/ "Padmé Amidala" 185.0 45.0 "brown" "light" "brown" 46.0 "female"
/ "Wat Tambor" 193.0 48.0 "none" "green, grey" "unknown" NaN "male"
/ "Lando Calrissian" 177.0 79.0 "black" "dark" "brown" 31.0 "male"
/ starwars %>% slice_sample(prop = 0.1)
pp t[(-10!nr)?nr]
/ === Table 8x14 ===
/ name height mass haircolor skincolor eyecolor birthyear sex
/ ------------------- ------ ----- --------- -------------- --------------- --------- ------
/ "Grievous" 216.0 159.0 "none" "brown, white" "green, yellow" NaN "male"
/ "Cliegg Lars" 183.0 NaN "brown" "fair" "blue" 82.0 "male"
/ "Plo Koon" 188.0 80.0 "none" "orange" "black" 22.0 "male"
/ "Cordé" 157.0 NaN "brown" "light" "brown" NaN "NA"
/ "Biggs Darklighter" 183.0 84.0 "black" "light" "brown" 24.0 "male"
/ starwars %>% filter(!is.na(height)) %>% slice_max(height, n = 3)
pp 3#'(..x@>height)rmnan["height";t]
/ === Table 3x14 ===
/ name height mass haircolor skincolor eyecolor birthyear sex
/ ------------- ------ ----- --------- --------- -------- --------- ------
/ "Yarael Poof" 264.0 NaN "none" "white" "yellow" NaN "male"
/ "Tarfful" 234.0 136.0 "brown" "brown" "blue" NaN "male"
/ "Lama Su" 229.0 88.0 "none" "grey" "black" NaN "male"
/ starwars %>% select(hair_color, skin_color, eye_color)
pp t[;!"haircolor skincolor eyecolor"]
/ === Table 87x3 ===
/ haircolor skincolor eyecolor
/ --------- ------------- --------
/ "blond" "fair" "blue"
/ "NA" "gold" "yellow"
/ "NA" "white, blue" "red"
/ "none" "white" "yellow"
/ "brown" "light" "brown"
/ starwars %>% select(hair_color:eye_color)
krng:{[t;x;y](k?x)_(1+k?y)#k:!t} / inclusive key range from x to y
pp krng[t;"haircolor";"eyecolor"]#t
/ === Table 87x3 ===
/ haircolor skincolor eyecolor
/ --------- ------------- --------
/ "blond" "fair" "blue"
/ "NA" "gold" "yellow"
/ "NA" "white, blue" "red"
/ "none" "white" "yellow"
/ "brown" "light" "brown"
/ starwars %>% select(!(hair_color:eye_color))
pp(krng[t;"haircolor";"eyecolor"]^(!t))#t
/ === Table 87x11 ===
/ name height mass birthyear sex gender homeworld species
/ ---------------- ------ ----- --------- -------- ----------- ---------- -------
/ "Luke Skywalker" 172.0 77.0 19.0 "male" "masculine" "Tatooine" "Human"
/ "C-3PO" 167.0 75.0 112.0 "none" "masculine" "Tatooine" "Droid"
/ "R2-D2" 96.0 32.0 33.0 "none" "masculine" "Naboo" "Droid"
/ "Darth Vader" 202.0 136.0 41.9 "male" "masculine" "Tatooine" "Human"
/ "Leia Organa" 150.0 49.0 19.0 "female" "feminine" "Alderaan" "Human"
/ starwars %>% select(ends_with("color"))
pp(rx/color$/!:)#t
/ === Table 87x3 ===
/ haircolor skincolor eyecolor
/ --------- ------------- --------
/ "blond" "fair" "blue"
/ "NA" "gold" "yellow"
/ "NA" "white, blue" "red"
/ "none" "white" "yellow"
/ "brown" "light" "brown"
/ starwars %>% select(home_world = homeworld)
pp t[;"homeworld"]
/ === Table 87x1 ===
/ homeworld
/ ----------
/ "Tatooine"
/ "Tatooine"
/ "Naboo"
/ "Tatooine"
/ "Alderaan"
/ starwars %>% rename(home_world = homeworld)
pp(,"homeworld")^t..[homeWorld:homeworld] / camelCase instead because already removed _
/ === Table 87x14 ===
/ name height mass haircolor skincolor eyecolor birthyear sex
/ ---------------- ------ ----- --------- ------------- -------- --------- --------
/ "Luke Skywalker" 172.0 77.0 "blond" "fair" "blue" 19.0 "male"
/ "C-3PO" 167.0 75.0 "NA" "gold" "yellow" 112.0 "none"
/ "R2-D2" 96.0 32.0 "NA" "white, blue" "red" 33.0 "none"
/ "Darth Vader" 202.0 136.0 "none" "white" "yellow" 41.9 "male"
/ "Leia Organa" 150.0 49.0 "brown" "light" "brown" 19.0 "female"
/ starwars %>% mutate(height_m = height / 100)
pp rmnan["height";t]..[heightm:height%100]
/ === Table 81x15 ===
/ name height mass haircolor skincolor eyecolor birthyear sex
/ ---------------- ------ ----- --------- ------------- -------- --------- --------
/ "Luke Skywalker" 172.0 77.0 "blond" "fair" "blue" 19.0 "male"
/ "C-3PO" 167.0 75.0 "NA" "gold" "yellow" 112.0 "none"
/ "R2-D2" 96.0 32.0 "NA" "white, blue" "red" 33.0 "none"
/ "Darth Vader" 202.0 136.0 "none" "white" "yellow" 41.9 "male"
/ "Leia Organa" 150.0 49.0 "brown" "light" "brown" 19.0 "female"
/ starwars %>% mutate(height_m = height / 100) %>% select(height_m, height, everything())
pp rmnan["height";t]..[heightm:height%100][;"heightm","height",(,"height")^!t]
/ === Table 81x15 ===
/ heightm height name mass haircolor skincolor eyecolor birthyear
/ ------- ------ ---------------- ----- --------- ------------- -------- ---------
/ 1.7 172.0 "Luke Skywalker" 77.0 "blond" "fair" "blue" 19.0
/ 1.7 167.0 "C-3PO" 75.0 "NA" "gold" "yellow" 112.0
/ 1.0 96.0 "R2-D2" 32.0 "NA" "white, blue" "red" 33.0
/ 2.0 202.0 "Darth Vader" 136.0 "none" "white" "yellow" 41.9
/ 1.5 150.0 "Leia Organa" 49.0 "brown" "light" "brown" 19.0
/ starwars %>% mutate( height_m = height / 100, BMI = mass / (height_m^2)) %>% select(BMI, everything())
pp rmnan["mass height";t]..[BMI:mass%(hm*hm:height%100)][;"BMI",!t]
/ === Table 59x15 ===
/ BMI name height mass haircolor skincolor eyecolor birthyear
/ ---- ---------------- ------ ----- --------- ------------- -------- ---------
/ 26.0 "Luke Skywalker" 172.0 77.0 "blond" "fair" "blue" 19.0
/ 26.9 "C-3PO" 167.0 75.0 "NA" "gold" "yellow" 112.0
/ 34.7 "R2-D2" 96.0 32.0 "NA" "white, blue" "red" 33.0
/ 33.3 "Darth Vader" 202.0 136.0 "none" "white" "yellow" 41.9
/ 21.8 "Leia Organa" 150.0 49.0 "brown" "light" "brown" 19.0
/ starwars %>% mutate( height_m = height / 100, BMI = mass / (height_m^2), .keep = "none")
pp rmnan["mass height";t].. ..[heightm:hm:height%100;BMI:mass%(hm*hm)]
/ === Table 59x2 ===
/ heightm BMI
/ ------- ----
/ 1.7 26.0
/ 1.7 26.9
/ 1.0 34.7
/ 2.0 33.3
/ 1.5 21.8
/ starwars %>% summarise(height = mean(height, na.rm = TRUE))
avg:{?[x:(nan)^x;(+/x)%#x;0n]}
pp@..[height:,avg t..height]
/ === Table 1x1 ===
/ height
/ ------
/ 174.6
/ starwars %>% group_by(species, sex) %>%
/ select(height, mass) %>%
/ summarise(
/ height = mean(height, na.rm = TRUE),
/ mass = mean(mass, na.rm = TRUE)
/ )
/ rby groups by cols c, summarises with f[t;by] (by contains grouping indices),
/ sorts result by c. Note that ordering the results is not necessary, but we do
/ it for compatibility with dplyr's example.
import"table"
rby:{[c;f;t]table.by[c;f;t]{x@<x y}/|c}
pp rby[!"species sex";{(avg'y=)'x[;!"height mass"]};t]
/ === Table 41x4 ===
/ species sex height mass
/ ---------- -------- ------ -----
/ "Aleena" "male" 79.0 15.0
/ "Besalisk" "male" 198.0 102.0
/ "Cerean" "male" 198.0 82.0
/ "Chagrian" "male" 196.0 NaN
/ "Clawdite" "female" 168.0 55.0
/ rby2 offers a more specific solution for the typical case where result
/ columns keep the same names as the columns they're computed from using a
/ particular function.
rby2:{[c;r;f;t]rby[c;{p.f@''(y=)'p.r#x};t]}
pp rby2[!"species sex";!"height mass";(avg;avg);t]
pp rby2[!"species sex";!"height mass";avg;t] / same function applied to height & mass
/ select(starwars, name)
pp t[;"name"]
/ === Table 87x1 ===
/ name
/ ----------------
/ "Luke Skywalker"
/ "C-3PO"
/ "R2-D2"
/ "Darth Vader"
/ "Leia Organa"
/ select(starwars, 1)
pp 1#t / same as above
/ name <- "color"; select(starwars, ends_with(name))
name:"color"; pp{~(!x)=(!x)-name}#t
/ === Table 87x3 ===
/ haircolor skincolor eyecolor
/ --------- ------------- --------
/ "blond" "fair" "blue"
/ "NA" "gold" "yellow"
/ "NA" "white, blue" "red"
/ "none" "white" "yellow"
/ "brown" "light" "brown"
/ df <- starwars %>% select(name, height, mass)
df:"name""height""mass"#t
/ mutate(df, height + 10)
pp df..["height+10":height+10]
/ === Table 87x4 ===
/ name height mass height+10
/ ---------------- ------ ----- ---------
/ "Luke Skywalker" 172.0 77.0 182.0
/ "C-3PO" 167.0 75.0 177.0
/ "R2-D2" 96.0 32.0 106.0
/ "Darth Vader" 202.0 136.0 212.0
/ "Leia Organa" 150.0 49.0 160.0
/ var <- seq(1, nrow(df)); mutate(df, new = var)
var:1+!#*df; pp df..[new:q.var]
/ === Table 87x4 ===
/ name height mass new
/ ---------------- ------ ----- ---
/ "Luke Skywalker" 172.0 77.0 1
/ "C-3PO" 167.0 75.0 2
/ "R2-D2" 96.0 32.0 3
/ "Darth Vader" 202.0 136.0 4
/ "Leia Organa" 150.0 49.0 5
/ starwars %>% filter(species == "Droid")
pp(1;..species="Droid")#t
/ === Table 6x14 ===
/ name height mass haircolor skincolor eyecolor birthyear sex
/ -------- ------ ----- --------- ------------- ----------- --------- ------
/ "C-3PO" 167.0 75.0 "NA" "gold" "yellow" 112.0 "none"
/ "R2-D2" 96.0 32.0 "NA" "white, blue" "red" 33.0 "none"
/ "R5-D4" 97.0 32.0 "NA" "white, red" "red" NaN "none"
/ "IG-88" 200.0 140.0 "none" "metal" "red" 15.0 "none"
/ "R4-P17" 96.0 NaN "none" "silver, red" "red, blue" NaN "none"
/ starwars %>% group_by(species) %>% summarise( n = n(), mass = mean(mass, na.rm = TRUE)) %>% filter( n > 1, mass > 50)
pp(1;..n>1;..mass>50)#rby["species";{..[n:=y@1; mass:avg'y=x..mass]};t]
/ === Table 9x3 ===
/ species n mass
/ ---------- -- ----
/ "Droid" 6 69.8
/ "Gungan" 3 74.0
/ "Human" 35 81.3
/ "Kaminoan" 2 88.0
/ "Mirialan" 2 53.1