docs: def by_col(cls, df, e,b, w=None, s=None, **kwargs):
          """
          Compute smoothing by columns in a dataframe.
  
          Parameters
          -----------
          df      :  pandas.DataFrame
                     a dataframe containing the data to be smoothed
          e       :  string or list of strings
                     the name or names of columns containing event variables to be
                     smoothed
          b       :  string or list of strings
                     the name or names of columns containing the population
                     variables to be smoothed
          w       :  pysal.weights.W or list of pysal.weights.W
                     the spatial weights object or objects to use with the
                     event-population pairs. If not provided and a weights object
                     is in the dataframe's metadata, that weights object will be
                     used.
          s       :  string or list of strings
                     the name or names of columns to use as a standard population
                     variable for the events `e` and at-risk populations `b`.
          inplace :  bool
                     a flag denoting whether to output a copy of `df` with the
                     relevant smoothed columns appended, or to append the columns
                     directly to `df` itself.
          **kwargs:  optional keyword arguments
                     optional keyword options that are passed directly to the
                     smoother.
  
          Returns
          ---------
          a copy of `df` containing the columns. Or, if `inplace`, this returns
          None, but implicitly adds columns to `df`.
          """
          if s is None:
              raise Exception('Standard population variable "s" must be supplied.')
          import pandas as pd
          if isinstance(e, str):
              e = [e]
          if isinstance(b, str):
              b = [b]
          if isinstance(s, str):
              s = [s]
          if w is None:
              found = False
              for k in df._metadata:
                  w = df.__dict__.get(w, None)
                  if isinstance(w, W):
                      found = True
                      break
              if not found:
                  raise Exception('Weights not provided and no weights attached to frame!'
                                      ' Please provide a weight or attach a weight to the'
                                      ' dataframe.')
          if isinstance(w, W):
              w = [w] * len(e)
          if not all(isinstance(wi, W) for wi in w):
              raise Exception('Weights object must be an instance of '
                              ' libpysal.weights.W!')
          b = b * len(e) if len(b) == 1 and len(e) > 1 else b
          s = s * len(e) if len(s) == 1 and len(e) > 1 else s
          try:
              assert len(e) == len(b)
              assert len(e) == len(s)
              assert len(e) == len(w)
          except AssertionError:
              raise ValueError('There is no one-to-one mapping between event'
                               ' variable and population at risk variable, and '
                               ' standard population variable, and spatial '
                               ' weights!')
          rdf = []
          max_len = 0
          for ei, bi, wi, si in zip(e, b, w, s):
              ename = ei
              bname = bi
              h = len(ei) // wi.n
              outcol = '_'.join(('-'.join((ename, bname)), cls.__name__.lower()))
              this_r = cls(df[ei], df[bi], w=wi, s=df[si], **kwargs).r
              max_len = 0 if len(this_r) > max_len else max_len
              rdf.append((outcol, this_r.tolist()))
          padded = (r[1] + [None] * max_len for r in rdf)
          rdf = list(zip((r[0] for r in rdf), padded))
          rdf = pd.DataFrame.from_items(rdf)
          return rdf