Use make.names Function in R (With Examples)


The make.names function is an essential utility within the R programming language, specifically designed to address complexities related to naming conventions within data structures. Its primary purpose is to take an existing set of identifiers, often provided as a character vector, and coerce them into syntactically valid names that adhere strictly to R’s internal rules for variable and column identifiers. This is critical when importing data from external sources—such as spreadsheets or databases—where column headers frequently contain illegal characters, spaces, or numeric prefixes that R cannot handle directly.

Understanding when and why to use make.names is fundamental for robust data cleaning and manipulation workflows in R. Names that are not syntactically valid can lead to unexpected errors, especially when attempting to access columns using the dollar sign ($) operator or when performing automated processing tasks. By normalizing these identifiers, the function ensures consistency and predictability across various R operations, including modeling, data subsetting, and reporting.

Understanding Syntactically Valid Names in R

In R, a strict set of rules governs what constitutes a legal identifier for objects, variables, or column names. These rules are in place to prevent ambiguity and ensure that the language interpreter can correctly parse and reference elements. Fundamentally, a name must start with either a letter (a-z, A-Z) or the dot character (.), provided the dot is not immediately followed by a number. Furthermore, valid names cannot contain spaces, mathematical operators (like + or -), or other special symbols (like @, #, or %).

When input data possesses column headers that violate these conventions—for instance, names such as “2023 Sales,” “Item-ID,” or “First Name”—R requires a mechanism to standardize these identifiers before they can be efficiently utilized. The standard R mechanism for handling this necessary translation and adjustment process is the make.names function. It automatically applies the necessary transformations, such as replacing illegal characters with dots (.) and prepending a prefix (typically “X”) if the name starts with a number.

This process of name coercion is not merely cosmetic; it is a structural necessity. If a data frame or matrix is created with invalid column names, accessing those columns programmatically becomes cumbersome, often requiring quotation marks and bracket notation (e.g., df["2023 Sales"]) rather than the far simpler and cleaner dollar-sign notation (e.g., df$X2023.Sales). By enforcing validity, make.names significantly enhances code readability and maintainability.

The Core Functionality and Syntax of make.names

The make.names function operates on a specified input vector, systematically checking each element against R’s syntactic requirements and modifying it as needed. It provides a simple, yet powerful, interface for handling this coercion, offering control over whether the resulting names must also be globally unique.

This function utilizes the following basic syntax structure:

make.names(names, unique = FALSE)

The parameters dictate the behavior of the coercion process:

  • names: This is the mandatory argument, representing the character vector (or object coercible to a character vector) that needs to be checked and potentially modified to adhere to R’s rules for syntactically valid names.
  • unique: This is an optional logical argument, defaulting to FALSE. When set to TRUE, the function not only ensures syntactic validity but also guarantees that every resulting name is distinct by appending numeric suffixes (e.g., .1, .2) to duplicate names.

The behavior of the function is highly standardized: any invalid characters are replaced by periods (.), and if a name starts with an invalid character (such as a digit), the prefix “X” is prepended to ensure the name begins with a valid character, thus satisfying R’s fundamental naming constraint. This systematic approach allows developers and data analysts to quickly clean up inconsistent header information prior to any serious analysis.

Practical Application 1: Coercing Numeric Vectors to Valid Names

One common scenario requiring name coercion involves transforming vectors composed solely of numeric values into valid identifiers. Since R identifiers cannot start with a digit, these numeric entries must be modified. Consider a case where a dataset uses years or numeric codes as column headers (e.g., 1, 4, 7). When we attempt to use these numbers as names, make.names intervenes to make them compatible with R‘s structure.

Suppose we begin with the following simple vector of numeric values that we intend to use as identifiers:

#create vector of numeric values
numeric_values <- c(1, 1, 4, 7, 8)

#create syntactically valid names from numeric values
make.names(numeric_values)

[1] "X1" "X1" "X4" "X7" "X8"

The resulting output demonstrates that R identifies names that start with a digit as invalid according to its rules for syntactically valid names, which mandate that identifiers must begin with a character or a dot. Consequently, to convert each numeric value into a valid name, R systematically prepends the string “X” to the beginning of each value. It is important to observe that two of the resulting names in this output are identical (“X1”), as the input vector contained duplicate entries (the initial two “1”s). This default behavior (with unique=FALSE) is preserved unless explicitly overridden.

Ensuring Uniqueness: Utilizing the unique=TRUE Argument

While syntactic validity is essential for parsing, ensuring that names are also unique is often crucial for data management, especially when working with functions that rely on distinct column identification, such as merging or aggregation. If an input vector contains duplicate values—which frequently occurs in datasets where categories or indices are reused—the default behavior of make.names will produce duplicate output names, as seen in the previous example.

To resolve this ambiguity and force the generated names to be distinct, we must explicitly set the unique argument to TRUE. This modification triggers R’s internal mechanism for deduplication, which appends a sequence of numeric suffixes, separated by a dot, to subsequent occurrences of identical names. This ensures that every element in the resulting vector is individually identifiable and addressable.

We can modify the previous example to demonstrate this enhanced functionality:

#create vector of numeric values
numeric_values <- c(1, 1, 4, 7, 8)

#create syntactically valid names from numeric values
make.names(numeric_values, unique=TRUE)

[1] "X1"   "X1.1" "X4"   "X7"   "X8"

The output clearly illustrates the result of the deduplication process. The first instance of the name remains “X1,” but the second instance is modified to “X1.1.” This sequential numbering guarantees that, regardless of the complexity or redundancy of the input character vector, the resulting output will consist of unique, syntactically valid names suitable for assigning to columns in a data frame or matrix. This feature is particularly valuable when processing large datasets where manual inspection for duplicates is impractical or impossible.

Practical Application 2: Assigning Valid Names to Data Structures

Beyond simple vector manipulation, a critical application of make.names is assigning clean, functional names to data structures that lack them, such as matrices created without explicit column definitions or data frames imported without headers. When a data structure is initialized without headers, R assigns generic, non-descriptive names, often represented as NULL for column names. Using make.names in conjunction with the structure’s dimensions allows for the rapid generation of sequential, valid identifiers.

Consider the following matrix in R, which has been created from a vector of numbers and currently lacks any meaningful column headers:

#create matrix
mat <- matrix(c(1, 2, 3, 7, 2, 4, 4, 6, 0, 1), ncol=2)

#view matrix
mat

     [,1] [,2]
[1,]    1    4
[2,]    2    4
[3,]    3    6
[4,]    7    0
[5,]    2    1

#view column names of matrix
colnames(mat)

NULL

As shown by the output of colnames(mat), the matrix currently has no formal column names, making programmatic access reliant on numeric indices (e.g., column 1, column 2). To improve usability and adherence to R conventions, we can leverage make.names() to generate descriptive column names based on the number of columns in the matrix. We use the sequence 1:ncol(mat) as the input vector to the function, which generates the numeric inputs “1” and “2.”

We then assign the output of make.names() directly to the colnames() attribute of the matrix:

#create column names for matrix
colnames(mat) <- make.names(1:ncol(mat))

#view updated matrix
mat

     X1 X2
[1,]  1  4
[2,]  2  4
[3,]  3  6
[4,]  7  0
[5,]  2  1

The matrix now features “X1” and “X2” as its column names, which are syntactically valid and easily referenced. This transformation allows for efficient data manipulation. For instance, extracting values from a specific column can now be achieved using the newly assigned name, improving the clarity and self-documentation of the code, as demonstrated below:

#view values in "X1" column of matrix
mat[, 'X1']

[1] 1 2 3 7 2

When and Why Name Coercion is Essential in Data Cleanup

The need for name coercion often arises during the initial data import stage, a phase frequently referred to as data wrangling or cleanup. Real-world data is rarely pristine; datasets imported from legacy systems, web scraping tools, or casual spreadsheet environments often contain headers that are problematic for R. Examples include headers using non-standard encodings, lengthy descriptive phrases separated by spaces, or the inclusion of units (e.g., “Temperature (°C)”) which contain illegal characters.

Using make.names proactively immediately after data import is a best practice. It transforms messy headers into uniform, dot-separated identifiers (e.g., “Temperature..C.”), ensuring that subsequent functions—whether they involve statistical modeling, visualization, or structural changes to the data frame—can operate without parsing errors related to column identification. Failure to implement this step can lead to silent errors or force the programmer to constantly rely on quoting column names, making complex scripts significantly more difficult to write and debug.

Furthermore, in scenarios involving automated reporting or dynamic data loading, the consistent output provided by make.names is invaluable. Since the function guarantees that the resulting names will follow the same syntactic structure every time, scripts written to process data streams can rely on standardized column names, even if the incoming data source occasionally varies its naming conventions or includes new, non-standard characters. This predictability is a cornerstone of scalable and reproducible data analysis in R.

Further Resources and Documentation

For users seeking comprehensive details regarding the specific implementation, edge cases, and additional features of the make.names function, the complete official documentation provided by the R core team is the definitive source. Accessing this documentation directly within the R console is highly recommended for deeper understanding.

You can retrieve the full documentation on how R handles the creation of syntactically valid names by executing the following command in your R session:

?make.names

Reviewing this documentation will provide insight into the exact rules R uses for coercion, including the handling of reserved keywords and different types of non-standard characters, allowing for mastery of this essential data preparation tool.

Additional Resources

The following tutorials explain how to perform other common operations in R:

Cite this article

Mohammed looti (2025). Use make.names Function in R (With Examples). PSYCHOLOGICAL STATISTICS. Retrieved from https://statistics.arabpsychology.com/use-make-names-function-in-r-with-examples/

Mohammed looti. "Use make.names Function in R (With Examples)." PSYCHOLOGICAL STATISTICS, 30 Oct. 2025, https://statistics.arabpsychology.com/use-make-names-function-in-r-with-examples/.

Mohammed looti. "Use make.names Function in R (With Examples)." PSYCHOLOGICAL STATISTICS, 2025. https://statistics.arabpsychology.com/use-make-names-function-in-r-with-examples/.

Mohammed looti (2025) 'Use make.names Function in R (With Examples)', PSYCHOLOGICAL STATISTICS. Available at: https://statistics.arabpsychology.com/use-make-names-function-in-r-with-examples/.

[1] Mohammed looti, "Use make.names Function in R (With Examples)," PSYCHOLOGICAL STATISTICS, vol. X, no. Y, ص Z-Z, October, 2025.

Mohammed looti. Use make.names Function in R (With Examples). PSYCHOLOGICAL STATISTICS. 2025;vol(issue):pages.

Download Post (.PDF)
Scroll to Top