@@ -130,9 +130,15 @@ def _pivot_multiselect(
130130 @staticmethod
131131 def _map_response_column_names (cname : str ) -> str :
132132 parts = cname .split ("__" , 1 )
133- if parts [0 ] == "response_options" :
134- return f"{ parts [1 ]} _options"
135- return "_" .join ([parts [1 ], parts [0 ].removeprefix ("response" )])
133+ match parts [0 ]:
134+ case "response_options" :
135+ return f"{ parts [1 ]} _options"
136+ case "response_response" :
137+ return f"{ parts [1 ]} _response"
138+ case "response_value" :
139+ return f"{ parts [1 ]} _score"
140+ case _:
141+ return "_" .join ([parts [1 ], parts [0 ].removeprefix ("response" )])
136142
137143 @staticmethod
138144 def _fill_item_response (* null_score_columns : str ) -> Generator [pl .Expr , None , None ]:
@@ -483,7 +489,29 @@ def _prepare_activity_columns(
483489 response_col = col .replace ("_index" , "_response" )
484490 df = df .with_columns ([(pl .col (col ) + 1 ).alias (response_col )])
485491
486- return df
492+ # Drop bare item columns that have _response versions
493+ response_bases = {
494+ col .replace ("_response" , "" )
495+ for col in df .columns
496+ if col .endswith ("_response" )
497+ }
498+ df = df .select (
499+ [
500+ col
501+ for col in df .columns
502+ if not (col in response_bases and f"{ col } _response" in df .columns )
503+ ]
504+ )
505+
506+ # Drop response metadata columns
507+ return df .select (
508+ [
509+ col
510+ for col in df .columns
511+ if not col .startswith (f"{ activity_prefix } _response_response_" )
512+ and not col .startswith (f"{ activity_prefix } _response_value_" )
513+ ]
514+ )
487515
488516 def _format_activity (self , df : pl .DataFrame , activity_name : str ) -> pl .DataFrame :
489517 """Format a single activity's data for REDCap import."""
0 commit comments