| Title: | R Client for the YouTube Analytics and Reporting API |
|---|---|
| Description: | Provides access to YouTube Analytics API v2 for retrieving YouTube Analytics data including views, engagement metrics, demographics, and revenue data. Supports OAuth 2.0 authentication and channel group management. See <https://developers.google.com/youtube/analytics/> for API documentation. |
| Authors: | Gaurav Sood [aut, cre] |
| Maintainer: | Gaurav Sood <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.6.0 |
| Built: | 2026-09-19 09:20:45 UTC |
| Source: | https://github.com/gojiplus/tubern |
Creates a new channel group.
add_group(resource_details, ...)add_group(resource_details, ...)
resource_details |
Named nested list. Required. Must provide: snippet with title (required), and optionally description and contentDetails with itemType |
... |
Additional arguments passed to |
named list
https://developers.google.com/youtube/analytics/reference/groups/insert
## Not run: add_group(list( snippet = list( title = "My Channel Group", description = "A group for organizing channels" ), contentDetails = list(itemType = "youtube#channel") )) ## End(Not run)## Not run: add_group(list( snippet = list( title = "My Channel Group", description = "A group for organizing channels" ), contentDetails = list(itemType = "youtube#channel") )) ## End(Not run)
Add Group Item
add_group_item(resource_details, ...)add_group_item(resource_details, ...)
resource_details |
Named nested list. Required. Must provide: groupId, resource.id |
... |
Additional arguments passed to |
named list
https://developers.google.com/youtube/analytics/reference/groupItems/insert
## Not run: add_group_item(list(groupId = "", resource.id = "hello")) ## End(Not run)## Not run: add_group_item(list(groupId = "", resource.id = "hello")) ## End(Not run)
Check API quota status and provide guidance
check_api_quota()check_api_quota()
Message about current quota usage (if available)
## Not run: check_api_quota() ## End(Not run)## Not run: check_api_quota() ## End(Not run)
Functions to transform YouTube Analytics API responses into common R data formats
Convenience functions for handling dates in YouTube Analytics API requests
Delete Group
delete_group(id, ...)delete_group(id, ...)
id |
String. Required. “The id parameter specifies the YouTube group ID of the group that is being deleted.” |
... |
Additional arguments passed to |
named list
https://developers.google.com/youtube/analytics/reference/groups/delete
## Not run: delete_group(id = "ABZZzGSIAAA") ## End(Not run)## Not run: delete_group(id = "ABZZzGSIAAA") ## End(Not run)
Delete Group Item
delete_group_item(id, ...)delete_group_item(id, ...)
id |
String. Required. “The id parameter specifies the YouTube group item ID for the group that is being deleted.” |
... |
Additional arguments passed to |
named list
https://developers.google.com/youtube/analytics/reference/groupItems/delete
## Not run: delete_group_item(id = "ABZZzGSIAAA") ## End(Not run)## Not run: delete_group_item(id = "ABZZzGSIAAA") ## End(Not run)
Custom error classes and improved error handling for YouTube Analytics API using rlang for modern error handling patterns.
Retrieves demographic breakdown of your audience by age and gender.
get_audience_demographics( date_range, end_date = NULL, ids = "channel==MINE", dimension = c("ageGroup", "gender"), metrics = "viewerPercentage", ... )get_audience_demographics( date_range, end_date = NULL, ids = "channel==MINE", dimension = c("ageGroup", "gender"), metrics = "viewerPercentage", ... )
date_range |
Date range string or start date |
end_date |
End date (only needed if date_range is a specific start date) |
ids |
Channel identifier (default: "channel==MINE") |
dimension |
Demographic dimension: "ageGroup", "gender", or both (default: both) |
metrics |
Vector of metrics to include. Defaults to '"viewerPercentage"', which is the only metric the viewer demographics report supports: the API rejects 'views' and 'estimatedMinutesWatched' against 'ageGroup'/'gender' with "The query is not supported." |
... |
Additional arguments passed to get_report() |
API response with demographic data
## Not run: # Full demographic breakdown get_audience_demographics("last_90_days") # Age groups only get_audience_demographics("this_month", dimension = "ageGroup") # Gender breakdown only get_audience_demographics("this_quarter", dimension = "gender") ## End(Not run)## Not run: # Full demographic breakdown get_audience_demographics("last_90_days") # Age groups only get_audience_demographics("this_month", dimension = "ageGroup") # Gender breakdown only get_audience_demographics("this_quarter", dimension = "gender") ## End(Not run)
Reads this package's own registry of dimension names, transcribed from Google's documentation. Local data; makes no API call.
get_available_dimensions(pattern = NULL)get_available_dimensions(pattern = NULL)
pattern |
Optional regex pattern to filter dimensions |
Named character vector of dimensions and descriptions
# Get all dimensions get_available_dimensions() # Get only geographic dimensions get_available_dimensions("country|city")# Get all dimensions get_available_dimensions() # Get only geographic dimensions get_available_dimensions("country|city")
Reads this package's own registry of metric names, transcribed from Google's documentation. Local data; makes no API call.
get_available_metrics(pattern = NULL)get_available_metrics(pattern = NULL)
pattern |
Optional regex pattern to filter metrics |
Named character vector of metrics and descriptions
# Get all metrics get_available_metrics() # Get only view-related metrics get_available_metrics("view")# Get all metrics get_available_metrics() # Get only view-related metrics get_available_metrics("view")
Retrieves key channel performance metrics for a specified time period.
get_channel_overview( date_range, end_date = NULL, ids = "channel==MINE", include_engagement = TRUE, include_subscribers = TRUE, ... )get_channel_overview( date_range, end_date = NULL, ids = "channel==MINE", include_engagement = TRUE, include_subscribers = TRUE, ... )
date_range |
Date range string like "last_30_days" or start date for custom range |
end_date |
End date (only needed if date_range is a specific start date) |
ids |
Channel identifier (default: "channel==MINE") |
include_engagement |
Logical. Include likes, dislikes, comments, shares (default: TRUE) |
include_subscribers |
Logical. Include subscriber metrics (default: TRUE) |
... |
Additional arguments passed to get_report() |
API response with channel overview data
## Not run: # Channel performance for last 30 days get_channel_overview("last_30_days") # Channel performance for specific date range get_channel_overview("2024-01-01", end_date = "2024-01-31") # Basic metrics only get_channel_overview("this_month", include_engagement = FALSE, include_subscribers = FALSE) ## End(Not run)## Not run: # Channel performance for last 30 days get_channel_overview("last_30_days") # Channel performance for specific date range get_channel_overview("2024-01-01", end_date = "2024-01-31") # Basic metrics only get_channel_overview("this_month", include_engagement = FALSE, include_subscribers = FALSE) ## End(Not run)
Returns the ranges this package understands. Local data; makes no API call.
get_common_date_ranges()get_common_date_ranges()
Named list of common date ranges
get_common_date_ranges()get_common_date_ranges()
Retrieves day-by-day performance metrics for trend analysis.
get_daily_performance( date_range, end_date = NULL, ids = "channel==MINE", metrics = c("views", "estimatedMinutesWatched"), ... )get_daily_performance( date_range, end_date = NULL, ids = "channel==MINE", metrics = c("views", "estimatedMinutesWatched"), ... )
date_range |
Date range string or start date |
end_date |
End date (only needed if date_range is a specific start date) |
ids |
Channel identifier (default: "channel==MINE") |
metrics |
Vector of metrics to include (default: views, estimatedMinutesWatched) |
... |
Additional arguments passed to get_report() |
API response with daily time series data
## Not run: # Daily views for last 30 days get_daily_performance("last_30_days") # Daily performance with engagement metrics get_daily_performance("this_month", metrics = c("views", "likes", "comments", "shares")) ## End(Not run)## Not run: # Daily views for last 30 days get_daily_performance("last_30_days") # Daily performance with engagement metrics get_daily_performance("this_month", metrics = c("views", "likes", "comments", "shares")) ## End(Not run)
Retrieves performance metrics broken down by country or other geographic dimensions.
get_geographic_performance( date_range, end_date = NULL, ids = "channel==MINE", dimension = "country", metrics = c("views", "estimatedMinutesWatched"), max_results = 25, ... )get_geographic_performance( date_range, end_date = NULL, ids = "channel==MINE", dimension = "country", metrics = c("views", "estimatedMinutesWatched"), max_results = 25, ... )
date_range |
Date range string or start date |
end_date |
End date (only needed if date_range is a specific start date) |
ids |
Channel identifier (default: "channel==MINE") |
dimension |
Geographic dimension: "country", "province", or "city" (default: "country") |
metrics |
Vector of metrics to include (default: views, estimatedMinutesWatched) |
max_results |
Number of results to return (default: 25) |
... |
Additional arguments passed to get_report() |
API response with geographic data
## Not run: # Top countries by views get_geographic_performance("last_30_days") # US states/provinces (requires US-only data) get_geographic_performance("this_month", dimension = "province", filters = "country==US" ) ## End(Not run)## Not run: # Top countries by views get_geographic_performance("last_30_days") # US states/provinces (requires US-only data) get_geographic_performance("this_month", dimension = "province", filters = "country==US" ) ## End(Not run)
Retrieves YouTube Analytics reports containing YouTube Analytics data.
get_report( ids, metrics, start_date = NULL, end_date = NULL, currency = NULL, dimensions = NULL, filters = NULL, include_historical_channel_data = NULL, max_results = NULL, sort = NULL, start_index = NULL, ... )get_report( ids, metrics, start_date = NULL, end_date = NULL, currency = NULL, dimensions = NULL, filters = NULL, include_historical_channel_data = NULL, max_results = NULL, sort = NULL, start_index = NULL, ... )
ids |
String. Channel or content owner identifier.
For channels: |
metrics |
String. Comma-separated list of YouTube Analytics metrics,
such as |
start_date |
String. Start date for the report. Can be in YYYY-MM-DD format or relative date like "last_30_days", "this_month", "yesterday". |
end_date |
String. End date for the report. Can be in YYYY-MM-DD format or a relative date. If NULL and start_date is relative, it is calculated automatically. |
currency |
Optional. String. Default is USD. Specifies what earnings
metrics like |
dimensions |
String. Optional. Comma-separated list of YouTube Analytics
dimensions, such as |
filters |
String. Optional. Dimension value filters. Multiple filters
can be separated by semicolons. For video filtering:
|
include_historical_channel_data |
Boolean. Default is FALSE. “Whether the API response should include channels' watch time and view data from the time period prior to when the channels were linked to the content owner.” |
max_results |
Integer. Optional. The maximum number of rows to include in the response. |
sort |
String. Optional A comma-separated list of dimensions or metrics that determine the sort order for YouTube |
start_index |
Integer. Optional. “The 1-based index of the first entity to retrieve.” |
... |
Additional arguments passed to |
named list
If you encounter a 404 "Not Found" error, check the following:
Ensure YouTube Analytics API is enabled in your Google Cloud Console project
Verify your authentication token is valid and has the correct scopes
Check that the channel ID (if using specific channel ID) exists and you have access to it
Use "channel==MINE" to access your own authenticated channel's
data
https://developers.google.com/youtube/analytics/reference/reports/query
## Not run: # Basic channel report get_report( ids = "channel==MINE", metrics = "views", start_date = "2020-01-01", end_date = "2020-01-31" ) # Report with video filtering (requires dimensions = "video") get_report( ids = "channel==MINE", metrics = "views,likes,comments", dimensions = "video", filters = "video==videoId1,videoId2", start_date = "2020-01-01", end_date = "2020-01-31" ) # Report with country filtering get_report( ids = "channel==MINE", metrics = "views", filters = "country==US", start_date = "2020-01-01", end_date = "2020-01-31" ) ## End(Not run)## Not run: # Basic channel report get_report( ids = "channel==MINE", metrics = "views", start_date = "2020-01-01", end_date = "2020-01-31" ) # Report with video filtering (requires dimensions = "video") get_report( ids = "channel==MINE", metrics = "views,likes,comments", dimensions = "video", filters = "video==videoId1,videoId2", start_date = "2020-01-01", end_date = "2020-01-31" ) # Report with country filtering get_report( ids = "channel==MINE", metrics = "views", filters = "country==US", start_date = "2020-01-01", end_date = "2020-01-31" ) ## End(Not run)
Retrieves revenue and monetization metrics.
get_revenue_report( date_range, end_date = NULL, ids = "channel==MINE", currency = "USD", include_cpm = TRUE, ... )get_revenue_report( date_range, end_date = NULL, ids = "channel==MINE", currency = "USD", include_cpm = TRUE, ... )
date_range |
Date range string or start date |
end_date |
End date (only needed if date_range is a specific start date) |
ids |
Channel identifier (default: "channel==MINE") |
currency |
Currency code (default: "USD") |
include_cpm |
Logical. Include CPM metrics (default: TRUE) |
... |
Additional arguments passed to get_report() |
API response with revenue data
## Not run: # Revenue report for last month get_revenue_report("last_month") # Revenue in different currency get_revenue_report("this_quarter", currency = "EUR") ## End(Not run)## Not run: # Revenue report for last month get_revenue_report("last_month") # Revenue in different currency get_revenue_report("this_quarter", currency = "EUR") ## End(Not run)
Retrieves performance metrics for individual videos, sorted by views.
get_top_videos( date_range, end_date = NULL, ids = "channel==MINE", max_results = 10, metrics = c("views", "likes", "comments"), ... )get_top_videos( date_range, end_date = NULL, ids = "channel==MINE", max_results = 10, metrics = c("views", "likes", "comments"), ... )
date_range |
Date range string or start date |
end_date |
End date (only needed if date_range is a specific start date) |
ids |
Channel identifier (default: "channel==MINE") |
max_results |
Number of top videos to return (default: 10) |
metrics |
Vector of metrics to include (default: views, likes, comments) |
... |
Additional arguments passed to get_report() |
API response with top videos data
## Not run: # Top 10 videos by views in last 30 days get_top_videos("last_30_days") # Top 25 videos with more metrics get_top_videos("this_month", max_results = 25, metrics = c("views", "likes", "comments", "shares", "estimatedMinutesWatched") ) ## End(Not run)## Not run: # Top 10 videos by views in last 30 days get_top_videos("last_30_days") # Top 25 videos with more metrics get_top_videos("this_month", max_results = 25, metrics = c("views", "likes", "comments", "shares", "estimatedMinutesWatched") ) ## End(Not run)
List Group Items
list_group_items(group_id, ...)list_group_items(group_id, ...)
group_id |
String. Required. ID of the group |
... |
Additional arguments passed to |
named list
https://developers.google.com/youtube/analytics/reference/groupItems/list
## Not run: list_group_items(group_id = "vponEBg8hrR1yBUX0Hz66Uc5WMk/vyGp6PvFo4RvsFtPoIWeCReyIC8") ## End(Not run)## Not run: list_group_items(group_id = "vponEBg8hrR1yBUX0Hz66Uc5WMk/vyGp6PvFo4RvsFtPoIWeCReyIC8") ## End(Not run)
List Groups
list_groups(filter, page_token = NULL, ...)list_groups(filter, page_token = NULL, ...)
filter |
Named Vector. Required. Only one of the two: id or mine. id: Comma-separated list of YouTube group ID(s) to retrieve. mine: Set to TRUE to retrieve all groups owned by the authenticated user. |
page_token |
String. Optional. Identifies a specific page in the result set that should be returned. |
... |
Additional arguments passed to |
named list
https://developers.google.com/youtube/analytics/reference/groups/list
## Not run: list_groups(filter = c(mine = TRUE)) ## End(Not run)## Not run: list_groups(filter = c(mine = TRUE)) ## End(Not run)
Pre-configured functions for common YouTube Analytics report types
Resolve date range with support for relative dates
resolve_date_range(start_date, end_date = NULL)resolve_date_range(start_date, end_date = NULL)
start_date |
Start date (can be relative like "last_30_days" or absolute like "2024-01-01") |
end_date |
End date (can be relative or absolute). If NULL and start_date is relative, it is calculated automatically |
List with resolved start_date and end_date as YYYY-MM-DD strings
# Relative date ranges resolve_date_range("last_30_days") resolve_date_range("this_month") resolve_date_range("last_quarter") # Absolute date ranges resolve_date_range("2024-01-01", "2024-01-31")# Relative date ranges resolve_date_range("last_30_days") resolve_date_range("this_month") resolve_date_range("last_quarter") # Absolute date ranges resolve_date_range("2024-01-01", "2024-01-31")
Provides access to YouTube Analytics API v2 for retrieving YouTube Analytics data including views, engagement metrics, demographics, and revenue data. Supports OAuth 2.0 authentication and channel group management. See https://developers.google.com/youtube/analytics/ for API documentation.
Maintainer: Gaurav Sood [email protected]
Authors:
Gaurav Sood [email protected]
Useful links:
DELETE
tubern_DELETE(path, query = NULL, body = "", ...)tubern_DELETE(path, query = NULL, body = "", ...)
path |
path to specific API request URL |
query |
query list |
body |
passing image through body |
... |
Ignored; kept for backward compatibility. |
list
GET
tubern_GET(path, query = NULL, ...)tubern_GET(path, query = NULL, ...)
path |
path to specific API request URL |
query |
query list |
... |
Ignored; kept for backward compatibility. |
list
POST
tubern_POST(path, query = NULL, body = "", ...)tubern_POST(path, query = NULL, body = "", ...)
path |
path to specific API request URL |
query |
query list |
body |
passing image through body |
... |
Ignored; kept for backward compatibility. |
list
PUT
tubern_PUT(path, query = NULL, body = "", ...)tubern_PUT(path, query = NULL, body = "", ...)
path |
path to specific API request URL |
query |
query list |
body |
passing image through body |
... |
Ignored; kept for backward compatibility. |
list
These are the names these functions had before 0.6.0. They still work and still return what they always did, but each warns once per session and will be removed in a future release.
add_groups(...) yt_to_dataframe(...) yt_to_tibble(...) diagnose_tubern(...)add_groups(...) yt_to_dataframe(...) yt_to_tibble(...) diagnose_tubern(...)
... |
Passed to the replacement. |
The renames were:
add_groups()add_group(), since it creates one
group and its siblings are delete_group() and
update_group()
yt_to_dataframe()yt_as_data_frame(), since
as_ is the convention for coercion
yt_to_tibble()yt_as_tibble(), likewise
diagnose_tubern()yt_diagnose(), since the
package name inside a function of that package says nothing
Whatever the replacement returns.
Update Groups
update_group(resource_details, ...)update_group(resource_details, ...)
resource_details |
Named nested list. Required. Must provide: id, snippet title |
... |
Additional arguments passed to |
named list
https://developers.google.com/youtube/analytics/reference/groups/update
## Not run: update_group(list(id = "ABZZzGSIAAA", snippet = list(title = "hello"))) ## End(Not run)## Not run: update_group(list(id = "ABZZzGSIAAA", snippet = list(title = "hello"))) ## End(Not run)
Internal validation functions for metrics, dimensions, and parameters using checkmate for robust parameter validation.
Transforms a YouTube Analytics API response into a clean data.frame with proper column names and types.
yt_as_data_frame(api_response, clean_names = TRUE, parse_dates = TRUE)yt_as_data_frame(api_response, clean_names = TRUE, parse_dates = TRUE)
api_response |
List returned from get_report() or other API functions |
clean_names |
Logical. Clean column names by removing special characters (default: TRUE) |
parse_dates |
Logical. Parse date columns to Date objects (default: TRUE) |
data.frame with transformed data, or NULL if no data available
## Not run: # Get data and convert to data.frame report <- get_channel_overview("last_30_days") df <- yt_as_data_frame(report) # Keep original column names df <- yt_as_data_frame(report, clean_names = FALSE) ## End(Not run)## Not run: # Get data and convert to data.frame report <- get_channel_overview("last_30_days") df <- yt_as_data_frame(report) # Keep original column names df <- yt_as_data_frame(report, clean_names = FALSE) ## End(Not run)
Convert API response to tibble (if tibble is available)
yt_as_tibble(api_response, ...)yt_as_tibble(api_response, ...)
api_response |
API response from YouTube Analytics |
... |
Additional arguments passed to yt_as_data_frame() |
tibble or data.frame if tibble not available
## Not run: report <- get_top_videos("last_7_days") tbl <- yt_as_tibble(report) ## End(Not run)## Not run: report <- get_top_videos("last_7_days") tbl <- yt_as_tibble(report) ## End(Not run)
Check if authentication token is in options
yt_check_token()yt_check_token()
Diagnose common tubern issues
yt_diagnose()yt_diagnose()
Diagnostic information about tubern setup
## Not run: yt_diagnose() ## End(Not run)## Not run: yt_diagnose() ## End(Not run)
Export data to CSV
yt_export_csv(api_response, filename = NULL, ...)yt_export_csv(api_response, filename = NULL, ...)
api_response |
API response from YouTube Analytics |
filename |
Output filename (default: auto-generated based on timestamp) |
... |
Additional arguments passed to yt_as_data_frame() |
Path to saved file
## Not run: report <- get_daily_performance("last_30_days") file_path <- yt_export_csv(report, "daily_performance.csv") ## End(Not run)## Not run: report <- get_daily_performance("last_30_days") file_path <- yt_export_csv(report, "daily_performance.csv") ## End(Not run)
Extract summary statistics from API response
yt_extract_summary(api_response)yt_extract_summary(api_response)
api_response |
API response from YouTube Analytics |
Named list with summary statistics
## Not run: report <- get_channel_overview("last_30_days") summary <- yt_extract_summary(report) print(summary) ## End(Not run)## Not run: report <- get_channel_overview("last_30_days") summary <- yt_extract_summary(report) print(summary) ## End(Not run)
Simplified OAuth2 setup for YouTube Analytics API. This function will automatically detect the required scope based on your needs and provide helpful setup guidance.
yt_oauth( app_id = NULL, app_secret = NULL, scope = "analytics", token = ".tubern-oauth", setup_guide = interactive(), ... )yt_oauth( app_id = NULL, app_secret = NULL, scope = "analytics", token = ".tubern-oauth", setup_guide = interactive(), ... )
app_id |
Client ID from Google Cloud Console; required; no default |
app_secret |
Client secret from Google Cloud Console; required; no default |
scope |
Character. One of:
|
token |
Path to the file holding the token. Defaults to
|
setup_guide |
Logical. Show the setup guide for first-time users (default: TRUE for interactive sessions) |
... |
Additional arguments passed to
|
The function looks for .tubern-oauth in the working directory. If it does not find one, it expects an application ID and a secret, and launches a browser so you can authorize the application.
The cache is deliberately not httr's shared .httr-oauth file. tubern authenticates with httr2 since 0.6.0, and other packages in the same working directory still read .httr-oauth expecting httr tokens.
Sets the google_token option and saves the token file. Called for those side effects.
https://developers.google.com/youtube/analytics/reference/
## Not run: # Basic setup (will show setup guide first time) yt_oauth("your-client-id.apps.googleusercontent.com", "your-client-secret") # Setup with monetary scope for revenue data yt_oauth("your-client-id.apps.googleusercontent.com", "your-client-secret", scope = "monetary") # Setup with full scope for group management (create/delete groups) yt_oauth("your-client-id.apps.googleusercontent.com", "your-client-secret", scope = "full") # Skip setup guide yt_oauth("your-client-id.apps.googleusercontent.com", "your-client-secret", setup_guide = FALSE) ## End(Not run)## Not run: # Basic setup (will show setup guide first time) yt_oauth("your-client-id.apps.googleusercontent.com", "your-client-secret") # Setup with monetary scope for revenue data yt_oauth("your-client-id.apps.googleusercontent.com", "your-client-secret", scope = "monetary") # Setup with full scope for group management (create/delete groups) yt_oauth("your-client-id.apps.googleusercontent.com", "your-client-secret", scope = "full") # Skip setup guide yt_oauth("your-client-id.apps.googleusercontent.com", "your-client-secret", setup_guide = FALSE) ## End(Not run)
Create a quick visualization of the data (if ggplot2 is available)
yt_quick_plot(api_response, x_col = NULL, y_col = NULL, chart_type = "auto")yt_quick_plot(api_response, x_col = NULL, y_col = NULL, chart_type = "auto")
api_response |
API response from YouTube Analytics |
x_col |
Column name for x-axis (auto-detected if NULL) |
y_col |
Column name for y-axis (auto-detected if NULL) |
chart_type |
Type of chart: "line", "bar", "point" (default: auto) |
ggplot object or base R plot if ggplot2 not available
## Not run: # Daily views over time daily_report <- get_daily_performance("last_30_days") yt_quick_plot(daily_report) # Top videos by views top_videos <- get_top_videos("last_7_days") yt_quick_plot(top_videos, chart_type = "bar") ## End(Not run)## Not run: # Daily views over time daily_report <- get_daily_performance("last_30_days") yt_quick_plot(daily_report) # Top videos by views top_videos <- get_top_videos("last_7_days") yt_quick_plot(top_videos, chart_type = "bar") ## End(Not run)