ENH: option to export df to Stata dataset with value labels
State: closed

GH38454

- [x] closes #38454
- [x] tests added / passed
- [x] Ensure all linting tests pass, see [here](https://pandas.pydata.org/pandas-docs/dev/development/contributing.html#code-standards) for how to run them
- [x] whatsnew entry

Labels:
name: Enhancement
name: IO Stata
description: read_stata, to_stata

Comments:
I added a `StataNonCatValueLabel` to format value labels for non categorical variables. In the `StataWriter`:
* added `value_labels` as optional argument. The format is as close to what is returned from `StataReader.value_labels()`, but the keys should be column names instead of column labels
* renamed `_is_col_cat` to `_has_value_labels`
* `_prepare_non_cat_value_labels` formats the value labels and checks that columns exist and are numeric
Thanks for the feedback! I made the typing changes and will go ahead and create a sample dta for some additional tests
You need to import Literal when type checking, and make sure `from __future__ import annotations` is at the top of the file.

An example:

https://github.com/pandas-dev/pandas/blob/accf345fdd4fb92056a5e62d4105fc8f4491ff2c/pandas/core/series.py#L141-L144
1. I created a variety of labelled types and checked that labels are being applied and displayed correctly in Stata:

![image](https://user-images.githubusercontent.com/16855568/116783227-9399ad00-aa5b-11eb-9113-a738c3b8d8d6.png)

![image](https://user-images.githubusercontent.com/16855568/116783231-9c8a7e80-aa5b-11eb-8028-14f7723983de.png)

2. The column names were being converted to valid Stata variables *before* the value labels were created. I added a check to use `StataWriter._converted_names` before checking the existing columns. I also moved the creation of `_converted_names` above `_prepare_pandas`, it was being populated in prepare pandas and reset to an empty dict in init
@bashtage I clarified the comments you mentioned. I left the type checking as is to be consistent with the rest of the project. If that's ok, I think everything is addressed. Thanks again for the feedback
If the CI is green, then we'll get it merged.  Thanks.

> If the CI is green, then we'll get it merged. Thanks.

@bashtage I can't tell where things are failing. Any suggestions?
Close and reopen to triger CI. 
@lmcindewar Can you take a look @jreback 's comments?
Failure is a random one due to codecov.
Typo in docstring

```
-        """ Encode value labels. """
+        """Encode value labels."""
```

@simonjayhawkins I'd completely missed your comment, I added a short release note. I think that should be it unless there's anything left from the previous reviews
LGTM.
@bashtage I haven't been able to nail down what's causing these type errors. It passes type checking with an added annotation on line 2542 in io/stata.py:
```python
self.data: DataFrame = data
```
but I wasn't sure if there was an underlying issue that needs to be fixed
Try adding `self.data = data` after the super in `__init__`
Failures seem unrelated to anything in this PR.
Can you rebase on master to fix the merge conflict. and then I think this is ready.
I rebased it.
@jreback I think this PR is in good shape and should be merged.  3 unrelated failures in doc tests.
@lmcindewar can you rebase so we can look into merging?
@bashtage I rebased it, let me know if there's anything else needed to merge it
Thanks @lmcindewar .  It would be great if you could do an example in a follow-up.
@bashtage Will do. Thanks again for all of the reviews