Beans and Legume Data Report
STAT 386 Final Project
Introduction
How did we pick the data?
This project demonstrates our complete data science workflow including data acquisition through an API call, wrangling, analysis, and insights. We selected data from the USDA FoodData Central (FDC) API, focusing specifically on Foundation Foods in the Legumes and Legume Products category. Our goal was to build functions that automatically retrieve nutrient profiles, clean the resulting JSON structure, organize nutrient fields into a usable dataset, and generate exploratory analyses such as summary visualizations and correlation heatmaps. This report describes the pipeline and summarizes how another user could replicate the workflow.
Main questions?
We began this analysis with two main questions:
- How do legume nutrients correlate with one another?
- What nutrients are present in the highest quantities in legumes?
Main takeaways from the analysis?
- Protein correlations: Protein shows high correlation with most nutrients (0.83-0.96) except sodium
- Calorie relationships: Calories correlate strongly with fat (0.67) and carbohydrates (0.71)
- Dominant minerals: Phosphorus is the most abundant mineral (1,076 mg/100g average), followed by magnesium (384 mg/100g)
- Data pipeline success: Successfully created a reproducible workflow from API data to cleaned dataset and visualizations
Data Collection
Data was collected from the USDA FoodData Central API, which provides standardized nutrient measurements for thousands of foods. To ensure reproducibility, we created:
- A function to read the API key (
read_api_key()) - A function to send paginated queries (
call_api())
The API returns a list of JSON objects containing metadata and nested nutrient lists. Pagination was handled through a simple loop (for pages 1–5), accumulating all returned rows into a single list.
Reproducibility Steps
To replicate data collection:
- Obtain an API key from the USDA FDC website
- Save it in a local
api.txtfile (one line only) - Run the package’s
main()script or callcall_api(api_key)manually
# Example usage
uv run python main.py # Regenerates legus_cleaned.csvData Wrangling and Cleaning
Complexity arose in our work because the nutrient values existed inside nested lists of dictionaries. We structured data wrangling around several modular functions.
Data Processing Pipeline
create_df(): Converts raw API rows into a pandas DataFrame and filters to dataType == "Foundation" to maintain consistency in nutrient definitions.
Nutrient Extraction: The raw JSON stores all nutrient values inside foodNutrients, a long list of nutrient dictionaries for each food item. To standardize extraction, we built:
extract_nutrient(nutrient_list, target): Returns the amount for a specific nutrientnutrient_cols(df): Applies the extractor to create one column per nutrient of interest
This step flattens the dataset into a traditional rectangular format suitable for analysis.
Data Cleaning Functions
clean_cols(df): Handles missing values (filling NA with zero), numeric rounding (two decimal places), and consistent column formatting.
categorize(df): Using regex, separates USDA description strings into: - Category (e.g., “Beans”) - Type (e.g., “black, cooked”)
reorder_df(df) and drop_unusedcols(df): Drop unused metadata fields and reorder columns for readability.
Final Output
The result is a clean, analysis-ready dataset saved as legus_cleaned.csv.
Analysis
Our analyses illustrate how the cleaned dataset can be explored to answer nutritional questions. The package includes three built-in visualizations.
avg_minerals_all(df)
Computes mean values for selected nutrients and produces a labeled bar chart. This visualization provides a high-level overview of nutrient density across the entire legume category.
Usage extensions: Users can modify the minerals list, group by Category or Type, or compare cooked vs. raw varieties.
corr_heatmap_minerals(df)
Computes pairwise correlations for all numeric columns and displays a bottom-triangle heatmap. This helps identify:
- Nutrients that co-occur frequently
- Redundant variables useful for dimensionality reduction
- Possible biological or processing-based nutrient relationships
sidebyside_boxes(df)
Creates side-by-side boxplots for Protein, Fat, Carbs, and Calories for all beans in the “Beans” Category. This helps identify how these nutrients compare across different bean varieties.
Findings
Nutrient Correlations
To answer the question of which nutrients correlate most with one another, we created a correlation heatmap with conditional formatting. The findings were interesting, yet consistent with our prior assumptions.
Key insights:
- Protein correlations: Protein was highly correlated with every nutrient we tracked outside of sodium (anywhere between 0.83 and 0.96)
- Calorie relationships: Calories were highly correlated with fat (0.67) and carbs (0.71), which was expected
- Sodium independence: Sodium showed minimal correlation with other nutrients, suggesting it’s primarily influenced by processing methods
Nutrient Amounts
Looking at nutrient amounts across the legume dataset was straightforward once we created our bar plot containing average mineral contents.
Dominant nutrients:
- Phosphorus: Highest amount at 1,076 mg per 100g sample (by far)
- Magnesium: Second highest at 384 mg per 100g sample
- Iron: 8.9 mg per 100g sample
- Zinc: 3.6 mg per 100g sample
Conclusion
Overall, we had a great time collecting, cleaning, and visualizing the USDA legume data. This project demonstrates how to design a reproducible data science workflow from scratch by:
- Collecting data through an external API
- Wrangling nested JSON structures into a clean dataset
- Producing meaningful analyses and visualizations
- Packaging everything so others can easily reuse it
The final package allows any user with a single API key to regenerate the full dataset and analyses exactly as we did, ensuring transparency, replicability, and extensibility.
Technical Achievements
- Modular function design: Each step of the pipeline is contained in reusable functions
- Error handling: Robust handling of missing data and API responses
- Visualization suite: Multiple analysis perspectives (correlations, distributions, averages)
- Package structure: Proper Python packaging with clear imports and documentation
Future Extensions
- Add serving-size normalization features
- Implement user-driven comparison exports
- Expand to other food categories beyond legumes
- Add statistical modeling capabilities
This project successfully demonstrates the complete data science process while providing valuable insights into legume nutrition that could inform dietary recommendations and food science research.