Your data lives in separate files. Products in one spreadsheet, ratings in another. January metrics in one CSV, February in the next. Customer info in the CRM export, transactions in the billing export. The Dataset Join module merges two or more datasets on a common column — like an SQL JOIN, but without writing SQL. Upload your files, pick the join column and join type, and get a combined dataset with join statistics in seconds.
What Is a Dataset Join?
A join combines rows from two or more datasets based on a shared column — a common key that exists in all of them. If you have a products table with columns for product_id, name, and price, and a ratings table with product_id, rating, and review_count, joining them on product_id produces a single table with product_id, name, price, rating, and review_count. Every row that matches on product_id gets combined.
This is the same concept as a SQL JOIN, a VLOOKUP in Excel, or a merge in pandas. The difference is that you do not need to know SQL, write formulas, or write code. You upload your files, tell the module which column to join on, and it handles the rest — including a detailed log of how many rows matched, how many were dropped, and what the combined result looks like.
There are four join types, and choosing the right one matters:
Inner join keeps only rows where the join column value exists in all datasets. If product_id 5 exists in the products table but not in the ratings table, it is excluded from the result. Use inner joins when you only want complete records — rows with data from every source.
Left join keeps all rows from the first (left) dataset and adds matching columns from the second dataset. If product_id 5 has no match in the ratings table, it still appears in the result, but the rating and review_count columns will be empty (NA). Use left joins when your first dataset is the primary source and you want to enrich it without losing any rows.
Right join is the mirror image: all rows from the second dataset are kept, with matching data from the first. Less commonly used, but important when the second dataset is your primary source.
Full join (outer join) keeps all rows from all datasets. If a product_id exists in only one table, it still appears with NAs for the columns from the other table. Use full joins for before/after comparisons — for example, joining January and February GSC data to see which pages appeared in only one month (gains and losses).
When to Use Dataset Join
Any time your analysis requires data that lives in separate files, Dataset Join is the first step. Here are the most common scenarios:
Enriching records: You have a customer list with IDs and demographics in one file, and purchase history with the same customer IDs in another. An inner or left join on customer_id combines them so you can analyze purchase behavior by demographic segment.
Time period comparison: You have Google Search Console data for January in one export and February in another. A full join on the page URL gives you a combined table where you can calculate month-over-month changes in clicks and impressions. Pages that appear in only one month show up as gains or losses with NA values in the other month's columns.
Cross-platform correlation: You have GA4 engagement metrics (sessions, bounce rate) in one file and GSC search metrics (impressions, clicks, CTR) in another. Joining on page URL lets you correlate search performance with on-site engagement — something neither platform can show you on its own.
Survey response merging: You ran the same survey across multiple cohorts or time periods and exported each separately. Joining on respondent ID (if tracked) or stacking them by shared column structure combines the datasets for unified analysis.
Product and transactional data: Your product catalog (SKU, name, category, cost) lives separately from your order data (SKU, quantity, revenue, date). Joining on SKU produces a dataset with both product attributes and sales performance, enabling margin analysis, category comparison, and product profitability reports.
What Data Do You Need?
You need two or more datasets (CSV files or connector sources). The key requirements are:
A common join column: All datasets must have a column with the same name that serves as the key. This can be any type — text (customer_id, page URL), numeric (product ID, order number), or date. The column name must be identical across all datasets. If one dataset calls it "product_id" and another calls it "id", you will need to rename one before joining.
Overlapping values: For inner joins, at least some values in the join column must match between datasets. If no values overlap, an inner join produces zero rows. The join log in the report shows match rates so you can diagnose this immediately.
Join type selection: Choose inner, left, right, or full based on what you need to preserve (see the descriptions above). The default is inner join.
There is no minimum row count — the module works as a utility for any dataset size, from small reference tables to large transactional datasets. When joining more than two datasets, they are joined sequentially: dataset 1 is joined with dataset 2, then the result is joined with dataset 3, and so on.
How to Read the Report
The report has five main sections, organized as a data pipeline story.
The Overview and Data Pipeline slides show the configuration: which datasets were provided, the join column, join type, and any preprocessing applied.
The Input Datasets table lists each input dataset with its name, row count, column count, and column names. This is your "before" snapshot — how much data went into the join from each source.
The Join Process Log is the most important diagnostic. It shows each join step sequentially: which dataset was joined, how many rows existed before the join, how many rows exist after, and how many columns were added. For an inner join, you expect the row count to decrease (only matches survive). For a full join, you expect it to stay the same or increase. If the row count drops dramatically on an inner join, it means few values matched — check for data quality issues in the join column (trailing spaces, case mismatches, different ID formats).
The Data Preview shows the first 20 rows of the joined result. Scan this to verify the join worked as expected — are the columns from both sources present? Do the values line up correctly? Are there unexpected NAs (which might indicate a mismatch in the join column)?
The Executive Summary provides a plain-language description of what was joined, how many records matched, and key observations about the combined dataset.
When to Use Something Else
If you need to stack datasets vertically (same columns, different rows) rather than merging them horizontally (same rows, different columns), you need concatenation, not a join. This is common when combining monthly exports of the same report.
If your join columns have slightly different values that should match (e.g., "John Smith" vs. "john smith", or "Product A" vs. "Product A" with an extra space), a standard join will miss these matches. You need fuzzy matching or data cleaning before joining.
If you need to join on multiple columns simultaneously (e.g., match on both customer_id AND date), or need complex join conditions (join where value is within a range), pre-process your data in SQL or a spreadsheet tool before uploading.
If your goal is not to combine data but to analyze it, jump directly to the appropriate analysis module. For example, if you want to compare metrics across time periods, a trend analysis may be more appropriate than joining and then analyzing manually.
The R Code Behind the Analysis
Every report includes the exact R code used to produce the results — reproducible, auditable, and citable. This is not AI-generated code that changes every run. The same data produces the same analysis every time.
The join operation uses merge() from base R and data.table for high-performance merging on large datasets. The all, all.x, and all.y parameters control the join type (inner, left, right, full). Join statistics are computed using nrow() before and after each merge step. Column name disambiguation follows R's default behavior, appending .x and .y suffixes to duplicate column names (excluding the join column). Every step is visible in the code tab of your report, so you can verify exactly what was done and reproduce it independently.