Monday, August 13, 2012

Rapido caso de uso con SAP HANA y R


AVISO: No soy un experto en SAP HANA o un experto en R expert, ni siquiera un experto en Python. Solo soy un joven con muchas ideas a quien le encanta escribir blogs.

El otro dia estaba pensando acerca de hacerlo algo interesante con SAP HANA y R, porque la gente parece no estar interesada en R aun, y eso es una verdadera pena...porque...R es alucinante...SAP HANA es mas alucinante...asi que juntarlos a los dos es...creo que ya tienen la idea...

Lo primero que se me vino a la cabeza fue una encuesta...nombre, apellido, pais, eded, sexo lenguage de programacion favorito...por supuesto...necesito mucho registros...mas de los que puedo generar a mano...asi que...un script de Python vino al rescate...luego pense...porque no tomo los nombres y apellidos de mis companheros de equipo, paises de origen, invento algunas edaded y otras cosas mas para hacer relleno. El script basicamente va a generar registros aleatorios para insertarlos en SAP HANA.

Vote_Generator.py
import os
import sys
import random
 
names = ["Anne", "Gigi", "Juergen", "Ingo", "Inga", "Alvaro", "Mario", "Julien",
"Mike", "Michael", "Karin", "Rui", "John", "Rocky", "Sebastian", "Kai-Yin",
"Hester", "Katrin", "Uwe", "Vitaliy"]
last_names = ["Hardy", "Read", "Schmerder", "Sauerzapf", "Bereza", "Tejada",
"Herger", "Vayssiere", "Flynn", "Byczkowski", "Schattka",
"Nogueira", "Mayerhofer", "Ongkowidjojo", "Wieczorek", "Gau", "Hilbrecht",
"Staehr", "Kylau", "Rudnytskiy"]
age = [24, 34, 40, 38, 28, 36, 35, 42, 30, 37]
sex = ["M", "F"]
country = ["Germany", "France", "Polland", "Peru", "Russia", "USA", "China",
"Philippines", "Portugal", "Spain"]
vote = ["ABAP", "Node", "Ruby", "Python", "R", "PHP", "ActionScript",
"Euphoria", "Java", "C++"]
 
def Generate_File(pSchema, pNumber):
    iNumber = 0
    pathname = os.path.dirname(sys.argv[0])
    pathname = os.path.abspath(pathname) + "\HANA_File.txt"
    myfile = open(pathname, "a")
    while iNumber < pNumber:
        r_names = random.randrange(0, 20)
        r_lastnames = random.randrange(0, 20)
        r_age = random.randrange(0, 10)
        r_sex = random.randrange(0, 2)
        r_country = random.randrange(0, 10)
        r_vote = random.randrange(0, 10)
        iNumber += 1
        myfile.write("insert into " + pSchema + " values('" +
        names[r_names] + "','" + last_names[r_lastnames] + "'," +
        str(age[r_age]) + ",'" + sex[r_sex] + "','" + country[r_country] +
        "','" + vote[r_vote] + "');\n")
    myfile.close()
    print 'The file ' + pathname + ' was written successfully'
 
schema = raw_input("Schema: \n")
num_files = input("How many records?: \n")
Generate_File(schema, num_files)

La execucion es bastante simple...pasamos el esquema y el numero de registros que queremos generar...para este blog...200,000 registros sonaron como un buen plan.


Como pueden ver...algunos nombre graciosos son generados aleatoriamente, pero despues de todo, somos un equipo asi que no creo que les importe mucho.

El siguiente paso era crear la tabla en SAP HANA y cargar los registros.


El objetivo de nuestro codigo de RHANA es tener informacion detallada sobre cuantos hombres o mujeres de cierta edad, de cierto pais votaron en la encuenta. Algo como CHINA -> 24 -->gt; F --> 890. (890 mujeres de 24 anhos de China votaron en la encuenta). Asi que desde luego, necesitamos crear una tabla para almacenar la informacion.


Con las piezas listas...estamos listos para codificar nuestro script...

HANA_R_Votes.sql
DROP TYPE T_VOTES_DETAIL;
 
CREATE TYPE T_VOTES_DETAIL AS TABLE (
COUNTRY VARCHAR(15),
AGE CHAR(2),
SEX CHAR(1),
FREQUENCY INTEGER
);
 
DROP PROCEDURE CALCULATE_VOTES;
DROP PROCEDURE GET_VOTES;
 
CREATE PROCEDURE CALCULATE_VOTES(IN votes VOTES, out votes_detail T_VOTES_DETAIL)
LANGUAGE RLANG AS
BEGIN
Country<-votes$COUNTRY
Age<-votes$AGE
Sex<-votes$SEX
Votes<-table(Country, Age, Sex)
Stats<-data.frame(Votes)
Stats<-subset(Stats,(Stats$Freq>0))
Stats<-Stats[order(Stats$Country,Stats$Age),]
votes_detail<-data.frame(COUNTRY=Stats$Country,AGE=Stats$Age,SEX=Stats$Sex,FREQUENCY=Stats$Freq)
END;
 
CREATE PROCEDURE GET_VOTES()
LANGUAGE SQLSCRIPT AS
BEGIN
tab_votes = SELECT * FROM VOTES;
CALL CALCULATE_VOTES(:tab_votes, T_VOTES_DETAIL);
INSERT INTO "VOTES_DETAIL" SELECT * FROM :T_VOTES_DETAIL;
END;
 
CALL GET_VOTES();
SELECT * FROM VOTES_DETAIL

Cuando todo esta listo, llamamos al procedimiento GET_VOTES() el cual va a leer los 200,000K registros de SAP HANA, enviarlos a nuestro servidor R para procesar la data y de ahi enviarlos nuevamente a SAP HANA para llenar una tabla con la informacion que queremos generar.


Si...todo el proceso tomo menos de 2 segundos...para 200,000K registros...nada mal...
Ahora podemos seleccionar los datos de nuestra tabla condensada...


Ahora que tenemos los datos que queremos, podemos utilizar las capacidades de analisis de SAP HANA para...analizar nuestros datos...



Debo decirlo...esto fue muy sencillo y rapido...podra no ser el mejor escenario, pero estoy seguro de que les dara una mejor perspectiva de lo que se puede hacer con SAP HANA y R.

Saludos,

Blag.

4 comments:

Durlak said...

Hola, creo que se podría hacer más rápido optimizando el código de R. Y se podría optimizar más, pero no se nada de SAP HANA y no tengo mucha idea de que es lo que interesa.

Votes<-as.data.frame(with(votes, table(COUNTRY, AGE, SEX))
Stats<-subset(Votes,(Votes$Freq>0))
Stats<-Stats[order(Stats$Country,Stats$AGE),]
votes_detail<-Stats

Alvaro "Blag" Tejada Galindo said...

Muchas gracias Durlak, como dije, no soy ningun experto en R asi que no se me ocurrio condensar el codigo de esa manera -:)

De todos modos, para 200,000K el proceso dura menos de 2 segundos...asi que la optimizacion no se notaria demasiado...

Saludos,

Blag.

Diego Dora said...

Muy bueno Alvaro! Felicitaciones por este Blog, encontramos con un colega un curso de R gratuito que están dando en una universidad en Estados Unidos.

Por si te interesa o a alguien más:

https://www.coursera.org/course/compdata

Un saludo,
Diego Dora.

Alvaro "Blag" Tejada Galindo said...

Diego!

Gracias por el comentario y por el enlace, ahorita lo reviso -:)

Saludos,

Blag.