From ef2677203899c7731f16ed23385d0604e8b69f24 Mon Sep 17 00:00:00 2001 From: junos Date: Mon, 3 Jul 2023 20:38:20 +0200 Subject: [PATCH] Add SAM question IDs. --- exploration/test_JCQ_reversal.py | 4 +- features/esm_COPE.py | 8 +- features/esm_JCQ.py | 29 ++++--- features/esm_SAM.py | 144 +++++++++++++++++++++++++++++++ 4 files changed, 167 insertions(+), 18 deletions(-) diff --git a/exploration/test_JCQ_reversal.py b/exploration/test_JCQ_reversal.py index bd9f854..67e83a8 100644 --- a/exploration/test_JCQ_reversal.py +++ b/exploration/test_JCQ_reversal.py @@ -15,7 +15,7 @@ # %% import pandas as pd -from features.esm_JCQ import dict_JCQ_demand_control_reverse +from features.esm_JCQ import DICT_JCQ_DEMAND_CONTROL_REVERSE # %% limesurvey_questions = pd.read_csv( @@ -115,7 +115,7 @@ limesurvey_control["qid"][0] # %% rows_demand_reverse = limesurvey_control["qid"].isin( - dict_JCQ_demand_control_reverse.keys() + DICT_JCQ_DEMAND_CONTROL_REVERSE.keys() ) limesurvey_control.loc[rows_demand_reverse, "score"] = ( 4 + 1 - limesurvey_control.loc[rows_demand_reverse, "score_original"] diff --git a/features/esm_COPE.py b/features/esm_COPE.py index 5cbb16f..f356625 100644 --- a/features/esm_COPE.py +++ b/features/esm_COPE.py @@ -3,7 +3,7 @@ import pandas as pd COPE_ORIGINAL_MAX = 4 COPE_ORIGINAL_MIN = 1 -dict_COPE_question_ids = { +DICT_COPE_QUESTION_IDS = { 164: ( "I took additional action to try to get rid of the problem", "Ik deed extra mijn best om er iets aan te doen", @@ -137,7 +137,7 @@ def reassign_question_ids(df_cope_cleaned: pd.DataFrame) -> pd.DataFrame: # Tabulate all possible answers to each question (group by question ID). # First, check that we anticipated all esm instructions. - for q_id in dict_COPE_question_ids.keys(): + for q_id in DICT_COPE_QUESTION_IDS.keys(): # Look for all questions ("instructions") occurring in the dataframe. actual_questions = df_esm_cope_unique_questions.loc[ df_esm_cope_unique_questions["question_id"] == q_id, @@ -145,7 +145,7 @@ def reassign_question_ids(df_cope_cleaned: pd.DataFrame) -> pd.DataFrame: ] # These are all answers to a given question (by q_id). questions_matches = actual_questions.str.startswith( - dict_COPE_question_ids.get(q_id) + DICT_COPE_QUESTION_IDS.get(q_id) ) # See if they are expected, i.e. included in the dictionary. if ~actual_questions.all(): @@ -160,7 +160,7 @@ def reassign_question_ids(df_cope_cleaned: pd.DataFrame) -> pd.DataFrame: lambda x: next( ( key - for key, values in dict_COPE_question_ids.items() + for key, values in DICT_COPE_QUESTION_IDS.items() if x.startswith(values) ), None, diff --git a/features/esm_JCQ.py b/features/esm_JCQ.py index 88073ce..035112c 100644 --- a/features/esm_JCQ.py +++ b/features/esm_JCQ.py @@ -3,7 +3,7 @@ import pandas as pd JCQ_ORIGINAL_MAX = 4 JCQ_ORIGINAL_MIN = 1 -dict_JCQ_demand_control_reverse = { +DICT_JCQ_DEMAND_CONTROL_REVERSE = { 75: ( "I was NOT asked", "Men legde mij geen overdreven", @@ -40,10 +40,14 @@ def reverse_jcq_demand_control_scoring( df_esm_jcq_demand_control: pd.DataFrame, ) -> pd.DataFrame: """ - This function recodes answers in Job content questionnaire by first incrementing them by 1, - to be in line with original (1-4) scoring. - Then, some answers are reversed (i.e. 1 becomes 4 etc.), because the questions are negatively phrased. - These answers are listed in dict_JCQ_demand_control_reverse and identified by their question ID. + Reverse JCQ demand and control answers. + + This function recodes answers in Job content questionnaire + by first incrementing them by 1, to be in line with original (1-4) scoring. + Then, some answers are reversed (i.e. 1 becomes 4 etc.), + because the questions are negatively phrased. + These answers are listed in DICT_JCQ_DEMAND_CONTROL_REVERSE + and identified by their question ID. However, the existing data is checked against literal phrasing of these questions to protect against wrong numbering of questions (differing question IDs). @@ -55,7 +59,8 @@ def reverse_jcq_demand_control_scoring( Returns ------- df_esm_jcq_demand_control: pd.DataFrame - The same dataframe with a column esm_user_score containing answers recoded and reversed. + The same dataframe with a column esm_user_score + containing answers recoded and reversed. """ df_esm_jcq_demand_control_unique_answers = ( df_esm_jcq_demand_control.groupby("question_id") @@ -64,7 +69,7 @@ def reverse_jcq_demand_control_scoring( .reset_index() ) # Tabulate all possible answers to each question (group by question ID). - for q_id in dict_JCQ_demand_control_reverse.keys(): + for q_id in DICT_JCQ_DEMAND_CONTROL_REVERSE.keys(): # Look through all answers that need to be reversed. possible_answers = df_esm_jcq_demand_control_unique_answers.loc[ df_esm_jcq_demand_control_unique_answers["question_id"] == q_id, @@ -72,7 +77,7 @@ def reverse_jcq_demand_control_scoring( ] # These are all answers to a given question (by q_id). answers_matches = possible_answers.str.startswith( - dict_JCQ_demand_control_reverse.get(q_id) + DICT_JCQ_DEMAND_CONTROL_REVERSE.get(q_id) ) # See if they are expected, i.e. included in the dictionary. if ~answers_matches.all(): @@ -85,15 +90,15 @@ def reverse_jcq_demand_control_scoring( df_esm_jcq_demand_control = df_esm_jcq_demand_control.assign( esm_user_score=lambda x: x.esm_user_answer_numeric + 1 ) - # Increment the original answer by 1 - # to keep in line with traditional scoring (JCQ_ORIGINAL_MIN - JCQ_ORIGINAL_MAX). + # Increment the original answer by 1 to keep in line + # with traditional scoring (JCQ_ORIGINAL_MIN - JCQ_ORIGINAL_MAX). df_esm_jcq_demand_control[ df_esm_jcq_demand_control["question_id"].isin( - dict_JCQ_demand_control_reverse.keys() + DICT_JCQ_DEMAND_CONTROL_REVERSE.keys() ) ] = df_esm_jcq_demand_control[ df_esm_jcq_demand_control["question_id"].isin( - dict_JCQ_demand_control_reverse.keys() + DICT_JCQ_DEMAND_CONTROL_REVERSE.keys() ) ].assign( esm_user_score=lambda x: JCQ_ORIGINAL_MAX diff --git a/features/esm_SAM.py b/features/esm_SAM.py index 4d75560..3a8191f 100644 --- a/features/esm_SAM.py +++ b/features/esm_SAM.py @@ -24,6 +24,150 @@ GROUP_QUESTIONNAIRES_BY = [ # within the same participant. +DICT_SAM_QUESTION_IDS = { + 87: ( + "Was there a particular event that created tension in you?", + "Was er een bepaalde gebeurtenis die spanning veroorzaakte?", + "Je prišlo do kakega dogodka, ki je v vas ustvaril napetost?", + ), + 88: ( + "Did this event make you feel anxious?", + "Voelde je je angstig door deze gebeurtenis?", + "Ste se zaradi tega dogodka počutili tesnobno?", + ), + 89: ( + "Will the outcome of this event be negative?", + "Zal de uitkomst van deze gebeurtenis negatief zijn? ", + "Bo izid tega dogodka negativen?", + ), + 90: ( + "How threatening was this event?", + "Hoe bedreigend was deze gebeurtenis?", + "Kako grozeč je bil ta dogodek?", + ), + 91: ( + "Is this going to have a negative impact on you?", + "Zal dit een negatieve impact op je hebben?", + "Ali bo to negativno vplivalo na vas?", + ), + 92: ( + "Is this going to have a positive impact on you?", + "Zal dit een positief effect op je hebben?", + "Ali bo to pozitivno vplivalo na vas?", + ), + 93: ( + "How eager are you to tackle this event?", + "Hoe graag wil je deze gebeurtenis aanpakken?", + "Kako zagnani ste bili pri spopadanju s tem dogodkom?", + ), + 94: ( + "To what extent can you become a stronger person because of this event?", + "In welke mate kan je een sterkere persoon worden door deze gebeurtenis?", + "V kolikšni meri lahko zaradi tega dogodka postanete močnejša oseba?", + ), + 95: ( + "To what extent are you excited thinking about the outcome of this event?", + "In welke mate ben je enthousiast bij de gedachte aan", + "V kolikšni meri vas misel na izid tega dogodka navdušuje?", + ), + 96: ( + "At what time did this event occur?", + "Hoe laat vond deze gebeurtenis plaats?", + "Kdaj se je ta dogodek zgodil?", + ), + 97: ( + "How long did this event last?", + "Hoe lang duurde deze gebeurtenis?", + "Kako dolgo je trajal ta dogodek?", + ), + 98: ( + "Was/is this event work-related?", + "Was/is deze gebeurtenis werkgerelateerd?", + "Je (bil) ta dogodek povezan s službo?", + ), + 99: ( + "Did this overall period create tension in you?", + "Heeft deze globale periode spanning veroorzaakt?", + "Je to obdobje kot celota v vas ustvarilo napetost?", + ), + 100: ( + "To what extent do you perceive this overall period as stressful?", + "In welke mate ervaar je deze globale periode als stressvol?", + "V kolikšni meri ste to obdobje dojemali kot stresno?", + ), + 101: ( + "Was there a particular event that created tension in you?", + "Was er een bepaalde gebeurtenis die spanning veroorzaakte?", + "Je prišlo do kakega dogodka, ki je v vas ustvaril napetost?", + ), + 102: ( + "Did this event make you feel anxious?", + "Voelde je je angstig door deze gebeurtenis?", + "Ste se zaradi tega dogodka počutili tesnobne?", + ), + 103: ( + "Will the outcome of this event be negative?", + "Zal de uitkomst van deze gebeurtenis negatief zijn? ", + "Bo izid tega dogodka negativen?", + ), + 104: ( + "How threatening was this event?", + "Hoe bedreigend was deze gebeurtenis?", + "Kako grozeč je bil ta dogodek?", + ), + 105: ( + "Is this going to have a negative impact on you?", + "Zal dit een negatieve impact op je hebben?", + "Ali bo to negativno vplivalo na vas?", + ), + 106: ( + "Is this going to have a positive impact on you?", + "Zal dit een positief effect op je hebben?", + "Ali bo to pozitivno vplivalo na vas?", + ), + 107: ( + "How eager are you to tackle this event?", + "Hoe graag wil je deze gebeurtenis aanpakken?", + "Kako zagnani ste bili, da se spopadete s tem dogodkom?", + ), + 108: ( + "To what extent can you become a stronger person because of this event?", + "In welke mate kan je een sterkere persoon worden door deze gebeurtenis?", + "V kolikšni meri lahko zaradi tega dogodka postanete močnejša oseba?", + ), + 109: ( + "To what extent are you excited thinking about the outcome of this event?", + "In welke mate ben je enthousiast bij de gedachte", + "V kolikšni meri vas misel na izid tega dogodka navdušuje?", + ), + 110: ( + "At what time did this event occur?", + "Hoe laat vond deze gebeurtenis plaats?", + "Kdaj se je ta dogodek zgodil?", + ), + 111: ( + "How long did this event last?", + "Hoe lang duurde deze gebeurtenis?", + "Kako dolgo je trajal ta dogodek?", + ), + 112: ( + "Was/is this event work-related?", + "Was/is deze gebeurtenis werkgerelateerd?", + "Je bil ali je ta dogodek povezan s službo?", + ), + 113: ( + "Did this overall period create tension in you?", + "Heeft deze globale periode spanning veroorzaakt?", + "Je to celo obdobje v vas ustvarilo napetost?", + ), + 114: ( + "To what extent do you perceive this overall period as stressful?", + "In welke mate ervaar je deze globale periode als stressvol?", + "V kolikšni meri ste celo to obdobje dojemali kot stresno?", + ), +} + + def extract_stressful_events(df_esm: pd.DataFrame) -> pd.DataFrame: """ Extract information about stressful events.