Sunday, January 11, 2009

Improving Version of RubyRx

Hi,

I fixed a bug in the previous version (the nested_hash method was not working properly, so I took it out and solved the problem another way).

I also added method_missing and turned the freq_by_trtgrp method into the far more dynamic freq method in conjunction with method_missing. The code now can take a frequency on any valid variable.

Below is the updated version of the code. I am looking forward to reviewing this in the class on Tuesday the 13th.

class DM
attr_accessor :sex, :race, :brthdtc, :trtgrp, :age

def initialize(obj)
@sex = obj[:sex]
@race = obj[:race]
@brthdtc = obj[:brthdtc]
@trtgrp = obj[:trtgrp]
@age = obj[:age]
end
end

class Output
attr_accessor :sex, :race, :age, :trtgrp

def initialize(sdtm_data)
@sdtm_data = sdtm_data
end

# Support templating of member data.
def get_binding
binding
end

def freq(by_var_list, *args)
by_var_str = ""
by_vars = by_var_list.split(/_and_/i)

if by_vars.length > 0
by_vars.each do |var|
by_var_str << "[e.#{var}]"
end
end

args.each do |arg|
instance_eval("@#{arg} = Hash.new unless instance_variable_defined?(:@#{arg})")

instance_eval("@#{arg}[:frequency] = Hash.new{|h,k| h[k] = Hash.new(&h.default_proc)} unless @#{arg}.keys.include?(:frequency)")

@sdtm_data.a.each do |e|
instance_eval("@#{arg}[:frequency]#{by_var_str}[e.#{arg}] = 0")
end

@sdtm_data.a.each do |e|
instance_eval("@#{arg}[:frequency]#{by_var_str}[e.#{arg}] += 1")
end
end

return self
end

def method_missing(sym, *args)
sym.to_s =~ /^(.*)_by_(.*)/i
method_name = $1
by_var_list = $2
instance_eval("#{method_name}('#{by_var_list}', :#{args.join(', :')})")
end
end

class DM_Table
attr_accessor :a

def initialize
@a = []
end

def << (obj)
@a << obj
end
end

dt = DM_Table.new
dt << trtgrp =""> 'Placebo', :sex => 'M', :race => 'BLACK', :brthdtc => '1968-10-01', :age => 52})
dt << trtgrp =""> 'Drug', :sex => 'F', :race => 'ASIAN', :brthdtc => '1970-07-04', :age => 17})
dt << trtgrp =""> 'Placebo', :sex => 'M', :race => 'WHITE', :brthdtc => '1968-10-01', :age => 88})
dt << trtgrp =""> 'Drug', :sex => 'M', :race => 'ASIAN', :brthdtc => '1970-07-04', :age => 12})
dt << trtgrp =""> 'Drug', :sex => 'F', :race => 'ASIAN', :brthdtc => '1970-07-04', :age => 21})
dt << trtgrp =""> 'Drug', :sex => 'M', :race => 'WHITE', :brthdtc => '1970-07-04', :age => 33})
dt << trtgrp =""> 'Placebo', :sex => 'F', :race => 'WHITE', :brthdtc => '1968-10-01', :age => 17})
dt << trtgrp =""> 'Placebo', :sex => 'M', :race => 'BLACK', :brthdtc => '1968-10-01', :age => 12})
dt << trtgrp =""> 'Placebo', :sex => 'M', :race => 'WHITE', :brthdtc => '1968-10-01', :age => 64})
dt << trtgrp =""> 'Drug', :sex => 'F', :race => 'ASIAN', :brthdtc => '1970-07-04', :age => 71})
dt << trtgrp =""> 'Placebo', :sex => 'M', :race => 'WHITE', :brthdtc => '1968-10-01', :age => 76})
dt << trtgrp =""> 'Drug', :sex => 'M', :race => 'ASIAN', :brthdtc => '1970-07-04', :age => 67})
dt << trtgrp =""> 'Drug', :sex => 'F', :race => 'WHITE', :brthdtc => '1970-07-04', :age => 6})
dt << trtgrp =""> 'Drug', :sex => 'M', :race => 'WHITE', :brthdtc => '1970-07-04', :age => 13})
dt << trtgrp =""> 'Placebo', :sex => 'F', :race => 'WHITE', :brthdtc => '1968-10-01', :age => 18})
dt << trtgrp =""> 'Placebo', :sex => 'F', :race => 'BLACK', :brthdtc => '1968-10-01', :age => 81})

begin
o = Output.new(dt)
o.freq('', :trtgrp).freq_by_trtgrp(:age, :sex, :race)
rescue => e
puts e
end

require "erb"
File.open('T14.2-Demo-Template.txt', 'r') do |t|
File.open('T14.2-Demo.rhtml', 'w') do |f|
f.puts ERB.new(t.readlines.to_s).result(o.get_binding)
end
end


This works in conjunction with the following text file template, called T14.2-Demo-Template.txt in the above code:

ACME Pharmaceuticals
Study XXXXXXX
Demographics Table

Placebo Drug
n=<%=@trtgrp[:frequency]['Placebo']%> n=<%=@trtgrp[:frequency]['Drug']%>
Sex
M <%=@sex[:frequency]['Placebo']['M']%> <%=@sex[:frequency]['Drug']['M']%>
F <%=@sex[:frequency]['Placebo']['F']%> <%=@sex[:frequency]['Drug']['F']%>

Race
White <%=@race[:frequency]['Placebo']['WHITE']%> <%=@race[:frequency]['Drug']['WHITE']%>
Black <%=@race[:frequency]['Placebo']['BLACK']%> <%=@race[:frequency]['Drug']['BLACK']%>
Asian <%=@race[:frequency]['Placebo']['ASIAN']%> <%=@race[:frequency]['Drug']['ASIAN']%>

Age

In the previous version of the code, the output was written to the console window. Now it is written to an output file, and looks like this:


ACME Pharmaceuticals
Study XXXXXXX
Demographics Table

Placebo Drug
n=8 n=8
Sex
M 5 4
F 3 4

Race
White 5 3
Black 3
Asian 5

Age

No comments: