Histogram

J

Justin To

I've been looking around to learn about histograms, and haven't had any
luck... can someone tell me how a histogram would work for something
like this:

Name, Age
Bob, 2
Jim, 2
Eric, 4
Rob, 5

How would I use a histogram to get a result like this:

Age | Names
2 | Bob, Jim
4 | Eric
5 | Rob

Thanks in advance!!!
 
R

Rob Biedenharn

I've been looking around to learn about histograms, and haven't had
any
luck... can someone tell me how a histogram would work for something
like this:

Name, Age
Bob, 2
Jim, 2
Eric, 4
Rob, 5

Depending on how you get that data, FasterCSV might be a good option,
but I'll just create a nested array for illustration.

ages = [ ['Bob', 2], ['Jim',2], ['Eric',4], ['Rob',5] ]
How would I use a histogram to get a result like this:

Age | Names
2 | Bob, Jim
4 | Eric
5 | Rob

Thanks in advance!!!


So the answer you want is: (note that I'm using a Hash since the keys
will be unique anyway)

histogram = { 2 => ['Bob','Jim'], 4 => ['Eric'], 5 => ['Rob'] }


So you could just use Enumerable#group_by (provided by the
ActiveSupport gem from Rails; yes, you can use it by itself). Of
course, it's also a simple matter to group them yourself:

histogram = Hash.new { |h,k| h[k] = [] } # hash that defaults values
to empty Arrays
ages.each {|name,age| histogram[age] << name }

If you need to produce that exact output:

puts "Age | Names"
histogram.sort_by {|age,names| age}.each do |age,names|
puts "%-3d | %s"%[age, names*', ']
end

Age | Names
2 | Bob, Jim
4 | Eric
5 | Rob

And I expect that you have a lot of thumbing through the Pickaxe to
understand all that ;-)

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
B

Boris Schmid

Justin said:
I've been looking around to learn about histograms, and haven't had any
luck... can someone tell me how a histogram would work for something
like this:

Name, Age
Bob, 2
Jim, 2
Eric, 4
Rob, 5

How would I use a histogram to get a result like this:

Age | Names
2 | Bob, Jim
4 | Eric
5 | Rob

Thanks in advance!!!

Assuming that you have a file that looks exactly like the one above,
this program does exactly what you asked.

# Reads in the datafile, and drops the 'Name, Age' line
data = IO.readlines("nameofdatafile")
data.shift

# Store the data in a hash
hash = Hash.new
data.each {|entry|
name = entry.split(",")[0]
age = entry.split(",")[1].to_i

hash[age] = [] unless hash.has_key?(age) # make sure there's a hash
key
hash[age] << name
}

# Pretty print it for each entry in the hash
puts "Age | Names"
hash.keys.each {|age|
printf("%3i | %s\n",age,hash[age].sort.join(", "))
}


For how histograms work: the general idea is that you create a number of
categories, and assign every single datapoint to its corresponding
category. One way to do this in ruby is to create a hash, in which each
key of the hash is a category, and the corresponding value of the hash
is an empty array. Then you proceed to fill these empty arrays with your
data, by distributing every datapoint to its corresponding array.

(Hopefully this is a general enough answer, it is in essence the same as
Rob's answer.)
 
B

Boris Schmid

hash[age] = [] unless hash.has_key?(age) # make sure there's a hash
key
hash[age] << name
}

That line containing only the word "key" is still part of the
"# make sure there's a hash" comment, and should not be on a
new line in your program. It just got word-wrapped by accident
when I posted it.
 
R

Robert Klemme

2008/6/6 Justin To said:
I've been looking around to learn about histograms, and haven't had any
luck... can someone tell me how a histogram would work for something
like this:

Name, Age
Bob, 2
Jim, 2
Eric, 4
Rob, 5

How would I use a histogram to get a result like this:

Age | Names
2 | Bob, Jim
4 | Eric
5 | Rob

Here's a variant:

10:43:33 $ /c/Temp/hist.rb
Age | Name
2 | Bob,Jim
4 | Eric
5 | Rob
11:03:55 $ cat /c/Temp/hist.rb
#!/bin/env ruby

hist = Hash.new {|h,k| h[k]=[]}
DATA.each do |line|
name, age = line.split /,\s*/
hist[Integer(age)] << name rescue nil
end

printf "%-4s | %s\n", "Age", "Name"
hist.sort_by {|k,| k}.each do |k,v|
printf "%4d | %s\n", k, v.join(',')
end

__END__
Name, Age
Bob, 2
Jim, 2
Eric, 4
Rob, 5
11:04:08 $

Kind regards

robert
 
P

Peña, Botp

From: Robert Klemme [mailto:[email protected]]=20
# Here's a variant:
<snip>

i was not going to send my soln since many had already sent theirs (and =
i was busy playing :)), yet i was surprise how similar was mine to =
robertk's, so... (just happy that i can be as good as robertk =
..sometimes ;)


C:\family\ruby>cat test.rb

# a =3D age
# n =3D name
hist =3D Hash.new { |h,a| h[a] =3D [] }
DATA.each do |entry|
n, a =3D entry.split /\s*?,\s*/
break if a.nil?
hist[a.to_i] << n.strip.capitalize
end

hist.sort_by{|a| a}.each do |a,n|
s =3D n.size
puts "#{a} -> #{s} #{"x"*s} (#{n.sort.join(', ')})"
end

__END__
Bob, 2
Jim ,2
eric, 4 # note:
RoB, 5 # i can put comments
bot, 4 #this is me :)
justin, 4, unneeded extras
joe,zero

--- no more here ----

C:\family\ruby>ruby test.rb
0 -> 1 x (Joe)
2 -> 2 xx (Bob, Jim)
4 -> 3 xxx (Bot, Eric, Justin)
5 -> 1 x (Rob)

C:\family\ruby>

i could have used ruport, but that would be overkill :)

kind regards -botp
 
R

Robert Klemme

2008/6/6 Pe=F1a said:
From: Robert Klemme [mailto:[email protected]]
# Here's a variant:
<snip>

i was not going to send my soln since many had already sent theirs (and i=
was busy playing :)),

Isn't it fun to play with something like this? :)
yet i was surprise how similar was mine to robertk's, so... (just happy t=
hat i can be as good as robertk ..sometimes ;)

Uh, oh, *cough* Thank you!
C:\family\ruby>cat test.rb

# a =3D age
# n =3D name
hist =3D Hash.new { |h,a| h[a] =3D [] }
DATA.each do |entry|
n, a =3D entry.split /\s*?,\s*/
break if a.nil?
hist[a.to_i] << n.strip.capitalize

It took me some time to realize that #to_i is actually the bit that
strips comments. Very clever!
end

hist.sort_by{|a| a}.each do |a,n|
s =3D n.size
puts "#{a} -> #{s} #{"x"*s} (#{n.sort.join(', ')})"
end

__END__
Bob, 2
Jim ,2
eric, 4 # note:
RoB, 5 # i can put comments
bot, 4 #this is me :)
justin, 4, unneeded extras
joe,zero

--- no more here ----

C:\family\ruby>ruby test.rb
0 -> 1 x (Joe)
2 -> 2 xx (Bob, Jim)
4 -> 3 xxx (Bot, Eric, Justin)
5 -> 1 x (Rob)

C:\family\ruby>

Nice!

Kind regards

robert


--=20
use.inject do |as, often| as.you_can - without end
 
R

Rick DeNatale

[Note: parts of this message were removed to make it a legal post.]

hist = Hash.new {|h,k| h[k]=[]}
DATA.each do |line|
name, age = line.split /,\s*/
hist[Integer(age)] << name rescue nil
end


or

hist = DATA.inject(Hash.new {|h,k| h[k]=[]}) do | h, line |
name, age = line.split /,\s*/
h[Integer(age)] << name rescue nil
h
end

Tsk, tsk, Robert you're not living up to your signature! <G>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,588
Members
45,100
Latest member
MelodeeFaj
Top