def roll(
        self,
        shifts: Mapping[Any, int] | None = None,
        roll_coords: bool = False,
        **shifts_kwargs: int,
    ) -> Self:
        """Roll this dataset by an offset along one or more dimensions.

        Unlike shift, roll treats the given dimensions as periodic, so will not
        create any missing values to be filled.

        Also unlike shift, roll may rotate all variables, including coordinates
        if specified. The direction of rotation is consistent with
        :py:func:`numpy.roll`.

        Parameters
        ----------
        shifts : mapping of hashable to int, optional
            A dict with keys matching dimensions and values given
            by integers to rotate each of the given dimensions. Positive
            offsets roll to the right; negative offsets roll to the left.
        roll_coords : bool, default: False
            Indicates whether to roll the coordinates by the offset too.
        **shifts_kwargs : {dim: offset, ...}, optional
            The keyword arguments form of ``shifts``.
            One of shifts or shifts_kwargs must be provided.

        Returns
        -------
        rolled : Dataset
            Dataset with the same attributes but rolled data and coordinates.

        See Also
        --------
        shift

        Examples
        --------
        >>> ds = xr.Dataset({"foo": ("x", list("abcde"))}, coords={"x": np.arange(5)})
        >>> ds.roll(x=2)
        <xarray.Dataset> Size: 60B
        Dimensions:  (x: 5)
        Coordinates:
          * x        (x) int64 40B 0 1 2 3 4
        Data variables:
            foo      (x) <U1 20B 'd' 'e' 'a' 'b' 'c'

        >>> ds.roll(x=2, roll_coords=True)
        <xarray.Dataset> Size: 60B
        Dimensions:  (x: 5)
        Coordinates:
          * x        (x) int64 40B 3 4 0 1 2
        Data variables:
            foo      (x) <U1 20B 'd' 'e' 'a' 'b' 'c'

        """
        shifts = either_dict_or_kwargs(shifts, shifts_kwargs, "roll")
        invalid = [k for k in shifts if k not in self.dims]
        if invalid:
            raise ValueError(
                f"Dimensions {invalid} not found in data dimensions {tuple(self.dims)}"
            )

        unrolled_vars: tuple[Hashable, ...]

        if roll_coords:
            indexes, index_vars = roll_indexes(self.xindexes, shifts)
            unrolled_vars = ()
        else:
            indexes = dict(self._indexes)
            index_vars = dict(self.xindexes.variables)
            unrolled_vars = tuple(self.coords)

        variables = {}
        for k, var in self.variables.items():
            if k in index_vars:
                variables[k] = index_vars[k]
            elif k not in unrolled_vars:
                variables[k] = var.roll(
                    shifts={k: s for k, s in shifts.items() if k in var.dims}
                )
            else:
                variables[k] = var

        return self._replace(variables, indexes=indexes)
Roll this dataset by an offset along one or more dimensions.

        Unlike shift, roll treats the given dimensions as periodic, so will not
        create any missing values to be filled.

        Also unlike shift, roll may rotate all variables, including coordinates
        if specified. The direction of rotation is consistent with
        :py:func:`numpy.roll`.

        Parameters
        ----------
        shifts : mapping of hashable to int, optional
            A dict with keys matching dimensions and values given
            by integers to rotate each of the given dimensions. Positive
            offsets roll to the right; negative offsets roll to the left.
        roll_coords : bool, default: False
            Indicates whether to roll the coordinates by the offset too.
        **shifts_kwargs : {dim: offset, ...}, optional
            The keyword arguments form of ``shifts``.
            One of shifts or shifts_kwargs must be provided.

        Returns
        -------
        rolled : Dataset
            Dataset with the same attributes but rolled data and coordinates.

        See Also
        --------
        shift

        Examples
        --------
        >>> ds = xr.Dataset({"foo": ("x", list("abcde"))}, coords={"x": np.arange(5)})
        >>> ds.roll(x=2)
        <xarray.Dataset> Size: 60B
        Dimensions:  (x: 5)
        Coordinates:
          * x        (x) int64 40B 0 1 2 3 4
        Data variables:
            foo      (x) <U1 20B 'd' 'e' 'a' 'b' 'c'

        >>> ds.roll(x=2, roll_coords=True)
        <xarray.Dataset> Size: 60B
        Dimensions:  (x: 5)
        Coordinates:
          * x        (x) int64 40B 3 4 0 1 2
        Data variables:
            foo      (x) <U1 20B 'd' 'e' 'a' 'b' 'c'

        
xarray/core/dataset.py