Linda, Pascal - My apologies for not describing it clearly. I will expand
on it below
R.E, Raul - Thank you, both are valid. REB's will probably be a better fit
for my situation.
To explain more what I'm doing with an example
Given a set of expenses, I want to calculate the item's cost relative to
the total spent in the family. I want to see the family total included in
the report.
For example, in this hypothetical example, 36% of my grocery expense is
from milk: 4 % (+/ 4 5 2)
txt1 =: 0 : 0
item,family,cost
milk,grocery,4
bread,grocery,5
cable,utilities,50
internet,utilities,25
phone,utilities,75
eggs,grocery,2
)
split =: (',',LF) (e.~ ];._1 ]) LF,]
txtb =: split txt1
col=. }. ((# txtb) $ 0 0 1) # txtb
toInt=. ([: ". ((' '&~: * CR&~:) # ]))"1
getCol =: [: }. (] #~ (#@] $ [))
family=: (0 1 0) getCol txtb
item=: (1 0 0) getCol txtb
cost=: toInt (0 0 1) gethCol txtb
famTotal=. family +//. cost
famTotalN =. (famTotal {~ (i.~~.) family)
pctOfFam =. cost % famTotalN
tbl=.item;family;cost;famTotalN;pctOfFam
NB. from http://www.jsoftware.com/jwiki/Essays/Inverted%20Table
] x1=: |:@:(<"_1&>)
NB. just for better presentation in email
x1 tbl
+---------+---------+--+---+--------+
|milk |grocery |4 |11 |0.363636|
+---------+---------+--+---+--------+
|bread |grocery |5 |11 |0.454545|
+---------+---------+--+---+--------+
|cable |utilities|50|150|0.333333|
+---------+---------+--+---+--------+
|internet |utilities|25|150|0.166667|
+---------+---------+--+---+--------+
|phone |utilities|75|150|0.5 |
+---------+---------+--+---+--------+
|eggs |grocery |2 |11 |0.181818|
+---------+---------+--+---+--------+
I need to do several calculations with the famTotal so distributing it to
famTotalN (making it parallel to the cost) makes the calculations simpler.
Both Raul's and R.E.'s solution will work
On Mon, Mar 9, 2015 at 3:22 AM, R.E. Boss <[email protected]> wrote:
>
> families=.55e6 $ (i.100000)
> val =: 55e6 $ 1
> famTotal =: families +//. val
>
> (famTotal{~(i.~~.) familie) also works.
>
> ts'(1-~ +/\ (~:families)) { famTotal' NB. JB
> 0.9683929 1.6777253e9
> ts'famTotal{~(i.~~.) families' NB. REB
> 0.59730098 1.0737444e9
> ts'(;ndx){famTotal#~#@>ndx=: families </.i.#families' NB. RM
> 3.0793607 2.6862264e9
>
>
> R.E. Boss
>
>
> > -----Original Message-----
> > From: [email protected] [mailto:programming-
> > [email protected]] On Behalf Of Raul Miller
> > Sent: maandag 9 maart 2015 6:11
> > To: Programming forum
> > Subject: Re: [Jprogramming] distributing nub to appropriate positions
> >
> > This might work?
> > ndx=: families </.i.#families
> > (;ndx){famTot#~#@>ndx
> >
> > Thanks,
> >
> > --
> > Raul
> >
> > On Mon, Mar 9, 2015 at 12:41 AM, Joe Bogner <[email protected]>
> > wrote:
> > > You are right. It won't be that easy since they are not adjacent. They
> are
> > > spread throughout in no pattern. That's the downside of using simple
> test
> > > data. I am glad you spotted it.
> > >
> > > I could have each row search for its family total in the table of
> family
> > > totals. I was concerned it would be slow and was hopeful there was a
> more
> > > efficient way. I should probably test it before jumping to that
> conclusion
> > > On Mar 9, 2015 12:25 AM, "Raul Miller" <[email protected]> wrote:
> > >
> > >> That'll work if your families are all adjacent.
> > >>
> > >> If they can be shuffled you'll need to do a bit more work.
> > >>
> > >> (But if they are not shuffled, why bother?)
> > >>
> > >> Thanks,
> > >>
> > >> --
> > >> Raul
> > >>
> > >> On Mon, Mar 9, 2015 at 12:22 AM, Joe Bogner <[email protected]>
> > wrote:
> > >> > This seems like it may be a viable solution:
> > >> >
> > >> > (1-~ +/\ (~:families)) { famTotal
> > >> >
> > >> > On Mon, Mar 9, 2015 at 12:15 AM, Joe Bogner <[email protected]>
> > wrote:
> > >> >
> > >> >> I am doing a +//. on a very large array that I need redistribute
> the
> > >> >> results back to the original positions.
> > >> >>
> > >> >> The dictionary has a solution that works well on small arrays[1],
> but
> > >> does
> > >> >> not work on my large array since it's using = to self classify
> > >> >>
> > >> >> Example:
> > >> >>
> > >> >> NB. create 3 fake families across 100 rows
> > >> >> families=: 1,(98$2),3
> > >> >> val=: 100 $1
> > >> >>
> > >> >> NB. sum by family
> > >> >> ] famTotal =: families +//. val
> > >> >> 1 98 1
> > >> >>
> > >> >> NB. desired output, result distributed to each row
> > >> >> ] desired =: famTotal ((+/ .*)=) families
> > >> >> 1 98 98 .... 1
> > >> >>
> > >> >>
> > >> >> NB. confirms desired matches family total
> > >> >> (~. ( i.~ families)) { desired
> > >> >> 4 3 3
> > >> >>
> > >> >> For my very large array:
> > >> >>
> > >> >> families=.55e6 $ (i.100000)
> > >> >> val =: 55e6 $ 1
> > >> >> famTotal =: families +//. val
> > >> >>
> > >> >> desired =: famTotal ((+/ .*)=) families
> > >> >> |out of memory
> > >> >>
> > >> >>
> > >> >> The reason why is because = families results in a huge array.
> > >> >>
> > >> >> How can I accomplish the same goal efficiently?
> > >> >>
> > >> >>
> > >> >>
> > >> >> 1 - http://www.jsoftware.com/help/dictionary/d221.htm
> > >> >> 2 - http://www.jsoftware.com/jwiki/Vocabulary/eq
> > >> >>
> > >> >
> ----------------------------------------------------------------------
> > >> > For information about J forums see
> > http://www.jsoftware.com/forums.htm
> > >> ----------------------------------------------------------------------
> > >> For information about J forums see
> > http://www.jsoftware.com/forums.htm
> > >>
> > > ----------------------------------------------------------------------
> > > For information about J forums see
> > http://www.jsoftware.com/forums.htm
> > ----------------------------------------------------------------------
> > For information about J forums see http://www.jsoftware.com/forums.htm
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm