Home > Software design >  Iterate over each row of a files where functions names are stored and call the function
Iterate over each row of a files where functions names are stored and call the function

Time:09-21

I have a excel file I use as parameters file and I retrieve data in a DataFrame

I iterate over parameters file (and store parameters in list of tuples) and dataframe to apply function when appropriate but as function is stored in paramtres files by its name which is a string it doesn't work

I tried using eval but it return None


def Patient(pat_ide):
    return '0'   str(pat_ide[4:])

def Sex(code):
    if code == 1:
        return 'M'
    else:
        return 'F'

# extract parameters from excel files
sdtm = [
    ('STUDYID','01-COV',None,None), 
    ('DOMAIN','DM',None,None), 
    ('USUBJID',None,'pat_ide',None), 
    ('SUBJID',None,'pat_ide','Patient'),    *** Patient function BUT STRING ***
    ('SEX',None,'dem_sex','Sex')            *** Sex function BUT STRING ***
]

for v in sdtm:
    for index, row in df.iterrows():
        # if assigned value
        if v[1] != 'NULL':
            df.loc[index, v[0]] = v[1]
        # else retrieve value from raw data
        else:
            if v[3] != 'NULL':
                df.loc[index, v[0]] =  eval('%s(%s)'%(v[3],row[v[2]]))  *** return None ***
            else:
                df.loc[index, v[0]] = row[v[2]]

CodePudding user response:

You can use something like this:

class Functions():
    def __init__(self):
        pass
    def alpha(self, a):
        return a*2

obj = Functions()
call_this_function = getattr(obj, 'alpha')
print(call_this_function(2))

CodePudding user response:

You can get objects from the local namespace using vars(). This returns a dictionary of all the defined objects, including the functions, e.g.

>>> vars()
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', 'Patient': <function Patient at 0x1007e52d0>, '__doc__': None, '__package__': None}

You can get your Patient function by name, using

fn = vars()['Patient']  # get the function.
fn()  # call the function

In your code this would become.


def Patient(pat_ide):
    return '0'   str(pat_ide[4:])

def Sex(code):
    if code == 1:
        return 'M'
    else:
        return 'F'

# extract parameters from excel files
sdtm = [
    ('STUDYID','01-COV',None,None), 
    ('DOMAIN','DM',None,None), 
    ('USUBJID',None,'pat_ide',None), 
    ('SUBJID',None,'pat_ide','Patient'),    *** Patient function BUT STRING ***
    ('SEX',None,'dem_sex','Sex')            *** Sex function BUT STRING ***
]

for v in sdtm:
    for index, row in df.iterrows():
        # if assigned value
        if v[1] != 'NULL':
            df.loc[index, v[0]] = v[1]
        # else retrieve value from raw data
        else:
            if v[3] != 'NULL':
                fn_name = v[3]         # Get the name of the function.
                fn = vars()[fn_name]   # Get the function.
                fn_arg = row[v[2]]     
                df.loc[index, v[0]] = fn(fn_arg)  # Call the function.
            else:
                df.loc[index, v[0]] = row[v[2]]

But note, you actually don't need to do this. Since your function name is coming from your list, why not just store the function in there directly, e.g.


def Patient(pat_ide):
    return '0'   str(pat_ide[4:])

def Sex(code):
    if code == 1:
        return 'M'
    else:
        return 'F'

# extract parameters from excel files
sdtm = [
    ('STUDYID','01-COV',None,None), 
    ('DOMAIN','DM',None,None), 
    ('USUBJID',None,'pat_ide',None), 
    ('SUBJID',None,'pat_ide',Patient),    *** Patient function
    ('SEX',None,'dem_sex',Sex)            *** Sex function


for v in sdtm:
    for index, row in df.iterrows():
        # if assigned value
        if v[1] != 'NULL':
            df.loc[index, v[0]] = v[1]
        # else retrieve value from raw data
        else:
            if v[3] != 'NULL':
                fn = v[3]         # Get the FUNCTION
                fn_arg = row[v[2]]     
                df.loc[index, v[0]] = fn(fn_arg)  # Call the function.
            else:
                df.loc[index, v[0]] = row[v[2]]

In Python you can store functions in lists.

  • Related