Multi-threading with DataFrames

to get suggestions for the current problem (about the use of an input string) it might be more useful to open a new topic with a more specific title

In principle a “simple calculator” seems feasible.
There’s a lot of work to do to make it truly functional, but just to start a seed


df=Dict("log"=>log, "sin"=>sin, "*"=>*,"+"=>+,"-"=>-,"^"=>^, "∘"=>∘)



function str2func(str)
    lff=findfirst('(', str)
    op=df[str[1:lff-1]]
    if !occursin('(',str[lff+1:end])
        par=split(str[lff+1:end-1],',')
        tp=tryparse.(Int,par)
        if all(isnothing,tp)
            return ((x,y)->(a->(b->(c->op(a,c))(b)))(x)(y))
        else
            n=only(filter(!isnothing,tp))
            return z->((x,y)->(a->(b->(c->op(a,c))(b)))(x)(y))(n,z)
        end
    else
        return (x...)->"not yet"
    end
end

julia> df_flows
6×5 DataFrame
 Row │ from    to      rp     tb     index 
     │ String  String  Int64  Int64  Int64
─────┼─────────────────────────────────────
   1 │ p1      d           1      3      1
   2 │ p1      d           1      5      2
   3 │ p2      d           1      7      3
   4 │ p2      d           1      4      4
   5 │ p1      d           2      6      5
   6 │ p2      d           2      8      6

julia> transform(df_flows,[3,4]=>ByRow(str2func("*(x,y)")))    
6×6 DataFrame
 Row │ from    to      rp     tb     index  rp_tb_function     
     │ String  String  Int64  Int64  Int64  Int64
─────┼─────────────────────────────────────────────────────    
   1 │ p1      d           1      3      1               3     
   2 │ p1      d           1      5      2               5     
   3 │ p2      d           1      7      3               7     
   4 │ p2      d           1      4      4               4     
   5 │ p1      d           2      6      5              12     
   6 │ p2      d           2      8      6              16     

julia> transform(df_flows,[3,4]=>ByRow(str2func("+(x,y)")))    
6×6 DataFrame
 Row │ from    to      rp     tb     index  rp_tb_function     
     │ String  String  Int64  Int64  Int64  Int64
─────┼─────────────────────────────────────────────────────    
   1 │ p1      d           1      3      1               4     
   2 │ p1      d           1      5      2               6     
   3 │ p2      d           1      7      3               8     
   4 │ p2      d           1      4      4               5     
   5 │ p1      d           2      6      5               8     
   6 │ p2      d           2      8      6              10     

julia> transform(df_flows,[4,3]=>ByRow(str2func("^(x,y)")))    
6×6 DataFrame
 Row │ from    to      rp     tb     index  tb_rp_function     
     │ String  String  Int64  Int64  Int64  Int64
─────┼─────────────────────────────────────────────────────    
   1 │ p1      d           1      3      1               3     
   2 │ p1      d           1      5      2               5     
   3 │ p2      d           1      7      3               7     
   4 │ p2      d           1      4      4               4     
   5 │ p1      d           2      6      5              36     
   6 │ p2      d           2      8      6              64     

julia> transform(df_flows,[4,3]=>ByRow(str2func("-(x,y)")))    
6×6 DataFrame
 Row │ from    to      rp     tb     index  tb_rp_function     
     │ String  String  Int64  Int64  Int64  Int64
─────┼─────────────────────────────────────────────────────    
   1 │ p1      d           1      3      1               2     
   2 │ p1      d           1      5      2               4     
   3 │ p2      d           1      7      3               6     
   4 │ p2      d           1      4      4               3     
   5 │ p1      d           2      6      5               4     
   6 │ p2      d           2      8      6               6     

julia> transform(df_flows,[4]=>ByRow(str2func("*(3,y)")))      
6×6 DataFrame
 Row │ from    to      rp     tb     index  tb_function        
     │ String  String  Int64  Int64  Int64  Int64
─────┼──────────────────────────────────────────────────       
   1 │ p1      d           1      3      1            9        
   2 │ p1      d           1      5      2           15        
   3 │ p2      d           1      7      3           21        
   4 │ p2      d           1      4      4           12        
   5 │ p1      d           2      6      5           18        
   6 │ p2      d           2      8      6           24        

julia> transform(df_flows,[4,3]=>ByRow(str2func("+(log(x),∘(sin, *(10,y)))")))
6×6 DataFrame
 Row │ from    to      rp     tb     index  tb_rp_function     
     │ String  String  Int64  Int64  Int64  String
─────┼─────────────────────────────────────────────────────    
   1 │ p1      d           1      3      1  not yet
   2 │ p1      d           1      5      2  not yet
   3 │ p2      d           1      7      3  not yet
   4 │ p2      d           1      4      4  not yet
   5 │ p1      d           2      6      5  not yet
   6 │ p2      d           2      8      6  not yet

the functions thus defined can be, in appropriate cases (associative operators), applied to more than 2 elements.
And in particular in the case of operators that have methods also defined on vectors, you can do without wrapping everything with ByRow

transform(df_flows,[3,4, 5]=>ByRow((x...)->reduce(str2func("+(x,y)"),x)))


transform(df_flows,[3,4, 5]=>(x...)->foldl(str2func("+(x,y)"),x))
1 Like