Repository: pyjanitor-devs/pyjanitor

Issue:
rename_column throw warning when column not found
I (finally) had an opportunity to use pyjanitor today! 😃 I ran into the unexpected behavior...

I used `rename_column` but had a typo in my first argument (the original column name). Instead of throwing a warning or error when the column wasn't found, pyjanitor continued the cleaning chain and returned a "partially-cleaned" DataFrame. It wasn't until later in my analysis that I realized the new column name didn't exist. 

I would expect pyjanitor to throw a warning or error in this case. I could *also* see this being a deliberate design choice. For example, a user may use the same logic to clean various datasets that  share some column names but not others. In that case, they might want pyjanitor to ignore columns not found.

Was this a deliberate choice? Or should `rename_column` throw an error when the column is not found (thus, also catching typos from sloppy coders like me along the way 😉)?
rename_column throw warning when column not found
I (finally) had an opportunity to use pyjanitor today! 😃 I ran into the unexpected behavior...

I used `rename_column` but had a typo in my first argument (the original column name). Instead of throwing a warning or error when the column wasn't found, pyjanitor continued the cleaning chain and returned a "partially-cleaned" DataFrame. It wasn't until later in my analysis that I realized the new column name didn't exist. 

I would expect pyjanitor to throw a warning or error in this case. I could *also* see this being a deliberate design choice. For example, a user may use the same logic to clean various datasets that  share some column names but not others. In that case, they might want pyjanitor to ignore columns not found.

Was this a deliberate choice? Or should `rename_column` throw an error when the column is not found (thus, also catching typos from sloppy coders like me along the way 😉)?


Discussion:
@Zsailer I think you caught a bug! Great catch! Let me see what I can do here. I'll loop back soon!
👍 

I'm happy to make a PR too, if you've got a lot on your plate. 
@Zsailer I think you caught a bug! Great catch! Let me see what I can do here. I'll loop back soon!
👍 

I'm happy to make a PR too, if you've got a lot on your plate. 

Resolving patch:
diff --git a/janitor/functions.py b/janitor/functions.py
--- a/janitor/functions.py
+++ b/janitor/functions.py
@@ -377,6 +377,8 @@ def rename_column(df, old, new):
     :param str new: The new column name.
     :returns: A pandas DataFrame.
     """
+    if old not in df.columns:
+        raise ValueError(f"{old} not present in dataframe columns!")
     return df.rename(columns={old: new})
 
 


Test patch:
diff --git a/tests/biology/test_join_fasta.py b/tests/biology/test_join_fasta.py
--- a/tests/biology/test_join_fasta.py
+++ b/tests/biology/test_join_fasta.py
@@ -9,7 +9,7 @@ def test_join_fasta(biodf):
     df = biodf.join_fasta(
         filename=TEST_DATA_DIR / "sequences.fasta",
         id_col="sequence_accession",
-        col_name="sequence"
+        col_name="sequence",
     )
 
     assert "sequence" in df.columns
diff --git a/tests/functions/test_add_columns.py b/tests/functions/test_add_columns.py
--- a/tests/functions/test_add_columns.py
+++ b/tests/functions/test_add_columns.py
@@ -1,10 +1,11 @@
 import numpy as np
 import pandas as pd
 import pytest
+from hypothesis import assume, given
+from hypothesis import strategies as st
+from hypothesis.extra.numpy import arrays
 
 from janitor.testing_utils.strategies import df_strategy
-from hypothesis import given, strategies as st, assume
-from hypothesis.extra.numpy import arrays
 
 
 @pytest.mark.test
@@ -12,7 +13,7 @@
 @given(
     df=df_strategy(),
     x_vals=st.floats(),
-    n_yvals=st.integers(min_value=0, max_value=100)
+    n_yvals=st.integers(min_value=0, max_value=100),
 )
 def test_add_columns(df, x_vals, n_yvals):
     """
diff --git a/tests/functions/test_rename_column.py b/tests/functions/test_rename_column.py
--- a/tests/functions/test_rename_column.py
+++ b/tests/functions/test_rename_column.py
@@ -1,13 +1,22 @@
 import pytest
 from hypothesis import given
 
-from janitor.testing_utils.strategies import df_strategy
+from janitor.testing_utils.fixtures import dataframe
 
 
 @pytest.mark.functions
-@given(df=df_strategy())
-def test_rename_column(df):
-    df = df.clean_names().rename_column("a", "index")
+def test_rename_column(dataframe):
+    df = dataframe.clean_names().rename_column("a", "index")
     assert set(df.columns) == set(
         ["index", "bell_chart", "decorated_elephant", "animals@#$%^", "cities"]
     )
+    assert "a" not in set(df.columns)
+
+
+@pytest.mark.functions
+def test_rename_column_absent_column(dataframe):
+    """
+    rename_column should raise an error if the column is absent.
+    """
+    with pytest.raises(ValueError):
+        dataframe.clean_names().rename_column("bb", "index")