Repository: IAMconsortium/pyam
Pull request #81 (2018-08-13 11:44:16)

Bugfix set ny unnamed series
# Please confirm that this PR has done the following:

- [x] Tests Added
- [x] Documentation Added
- [x] Description in RELEASE_NOTES.md Added

# Description

This PR fixes a bug when adding an unnamed series using `set_meta()` and not providing a `name` kwarg.

danielhuppmann: going ahead and merging since everybody else is on vacation...

Patch:
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index f0d92f3..e5b566a 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -1,6 +1,7 @@
 
 # Next Release
 
+- (#81)[https://github.com/IAMconsortium/pyam/pull/81] Bug-fix when using `set_meta()` with unnamed pd.Series and no `name` kwarg
 - (#80)[https://github.com/IAMconsortium/pyam/pull/80] Extend the pseudo-regexp syntax for filtering in `pattern_match()`
 - (#73)[https://github.com/IAMconsortium/pyam/pull/73] Adds ability to remove labels for markers, colors, or linestyles
 - (#72)[https://github.com/IAMconsortium/pyam/pull/72] line_plot now drops NaNs so that lines are fully plotted
diff --git a/pyam/core.py b/pyam/core.py
index fd1b0df..680aa12 100644
--- a/pyam/core.py
+++ b/pyam/core.py
@@ -262,17 +262,17 @@ class IamDataFrame(object):
         self.meta['exclude'] = False
 
     def set_meta(self, meta, name=None, index=None):
-        """Add metadata columns as pd.Series or list
+        """Add metadata columns as pd.Series, list or value (int/float/str)
 
         Parameters
         ----------
-        meta: pd.Series, list, int or str
+        meta: pd.Series, list, int, float or str
             column to be added to metadata
             (by `['model', 'scenario']` index if possible)
-        name: str
-            meta column name (if not given by meta pd.Series.name)
+        name: str, optional
+            meta column name (defaults to meta pd.Series.name)
         index: pyam.IamDataFrame or pd.MultiIndex, optional
-            index to be used for setting meta column
+            index to be used for setting meta column (`['model', 'scenario']`)
         """
         if not name and not hasattr(meta, 'name'):
             raise ValueError('Must pass a name or use a pd.Series')
@@ -281,7 +281,7 @@ class IamDataFrame(object):
         if index is not None and isinstance(index, IamDataFrame):
             index = index.meta.index
 
-        # create pd.Series from index and meta if provided
+        # create pd.Series from meta, index and name if provided
         _meta = meta if index is None else pd.Series(data=meta, index=index,
                                                      name=name)
 
@@ -292,14 +292,11 @@ class IamDataFrame(object):
 
         # if not possible to append by index
         if not append_by_idx:
-            if islistable(meta):
-                self.meta[name] = list(meta)
-            else:
-                self.meta[name] = meta
+            self.meta[name] = list(meta) if islistable(meta) else meta
             return  # EXIT FUNCTION
 
         # else append by index
-        name = name or _meta.name
+        _meta.name = name = name or _meta.name
 
         # reduce index dimensions to model-scenario only
         _meta = (


Test patch:
diff --git a/tests/test_core.py b/tests/test_core.py
index 3fc4740..35eee8e 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -353,6 +353,23 @@ def test_set_meta_as_named_series(meta_df):
     pd.testing.assert_series_equal(obs, exp)
 
 
+def test_set_meta_as_unnamed_series(meta_df):
+    idx = pd.MultiIndex(levels=[['a_scenario'], ['a_model'], ['a_region']],
+                        labels=[[0], [0], [0]],
+                        names=['scenario', 'model', 'region'])
+
+    s = pd.Series(data=[0.3], index=idx)
+    meta_df.set_meta(s, name='meta_values')
+
+    idx = pd.MultiIndex(levels=[['a_model'], ['a_scenario', 'a_scenario2']],
+                        labels=[[0, 0], [0, 1]], names=['model', 'scenario'])
+    exp = pd.Series(data=[0.3, np.nan], index=idx)
+    exp.name = 'meta_values'
+
+    obs = meta_df['meta_values']
+    pd.testing.assert_series_equal(obs, exp)
+
+
 def test_set_meta_non_unique_index_fail(meta_df):
     idx = pd.MultiIndex(levels=[['a_model'], ['a_scenario'], ['a', 'b']],
                         labels=[[0, 0], [0, 0], [0, 1]],