Tutorials › Exam PA - Predictive Analytics › Checking Dimensions with dim(), nrow(), and ncol()

Exam PA · Data Structures and Exploratory Summaries · Tutorial 102 of 966

Checking Dimensions with dim(), nrow(), and ncol()

Use R’s dimension functions to verify a data frame’s size and judge whether its row count represents the records the analysis intends to include.

Beginner 9 min read

What You'll Learn

  • Read the row and column counts returned by dim(), nrow(), and ncol().
  • Check that the three functions give consistent results.
  • Relate a row count to the dataset’s intended observational unit.
  • Distinguish records from unique people, policies, or other entities.
  • Interpret data frames with rows but no columns, or columns but no rows.
  • Recognize what dimension checks can and cannot establish.

Why Check a Data Frame’s Dimensions?

Before summarizing or modeling data, verify its basic size. A row count can reveal that an expected extract is short, while a column count can reveal that a file contains more or fewer variables than intended. These checks are quick, but their interpretation depends on knowing what one row is supposed to represent.

In R, the functions dim(), nrow(), and ncol() report the dimensions of a data frame. Used together, they help confirm that the object has the expected structure. They do not, by themselves, establish that the records are correct, complete, or representative of the intended population. That distinction matters in predictive analytics and is aligned with the SOA Exam PA (Predictive Analytics) syllabus.

Definition: For a data frame with \(n\) rows and \(p\) columns, its dimensions are the ordered pair \((n,p)\). In R, dim(data) returns a vector containing the row count followed by the column count; nrow(data) returns the row count; and ncol(data) returns the column count. When each row represents one observational unit and each column represents one variable, these counts describe the numbers of recorded units and variables in the data frame.

What the Three Functions Return

For an ordinary data frame, dim(data) reports both counts in a fixed order: rows first, columns second. For example, a result of c(240, 7) means 240 rows and 7 columns. It does not mean 240 columns and 7 rows. The individual functions return just one count each, which makes them convenient when only one dimension is needed.

The relationship among the functions follows directly from what they report. If the data frame has \(n\) rows and \(p\) columns, then:

$$ \operatorname{dim}(\text{data}) = (n,p), \qquad \operatorname{nrow}(\text{data}) = n, \qquad \operatorname{ncol}(\text{data}) = p. $$

Therefore, the first element of dim(data) agrees with nrow(data), and its second element agrees with ncol(data). This follows from the definitions of the functions, not from counting entries in the columns. That point is important: a data frame can have rows even when it has no columns, so counting column entries would not establish the row count in every case.

A dimension check answers a structural question: “How many rows and columns does this object currently have?” It does not answer whether each row is a distinct policyholder, whether all expected dates are present, or whether the data cover the intended population. Those questions require context about how the data were assembled and what the rows represent.

Worked Examples

Worked Example: Checking an Expected Policy-Month Extract

Suppose an analyst has a hypothetical data frame called monthly_exposure. The extract is intended to contain one row for each of 320 eligible policy-months and six variables. The analyst runs dim(monthly_exposure) and sees c(308, 6). Use all three dimension functions to describe the result and assess what it implies.

Method: compare the reported dimensions with the intended dimensions. The first component of c(308, 6) is the number of rows, so the data frame has 308 rows. Its second component is the number of columns, so it has 6 columns.

The separate checks are nrow(monthly_exposure), which returns 308, and ncol(monthly_exposure), which returns 6. The checks agree with the two components of dim(monthly_exposure).

Under the stated design of one row per eligible policy-month, the observed row count is 12 less than intended: \(320-308=12\). The column count matches the stated design of six variables. The dimension check therefore identifies a row-count discrepancy, but it does not explain its cause. For example, rows might have been excluded during extraction, or the stated target count might not match the final eligibility rules.

Common mistake avoided: Do not conclude that 12 policyholders are missing. The intended unit is a policy-month, not necessarily a distinct policyholder, and the dimension check does not identify which units are absent. The next step is to investigate the extract’s scope and construction, not to infer an explanation from the counts alone.

R check: dim(monthly_exposure) returns c(308, 6); nrow(monthly_exposure) returns 308; ncol(monthly_exposure) returns 6.

Worked Example: Rows Are Events, Not Unique Policies

A hypothetical claims-event data frame is intended to include all 186 event records for a review period. Each row represents one event; some policies can therefore appear in more than one row. The analyst reports dim(claim_events) as c(186, 5). Given that 14 rows are repeat events from policies already represented and the other 172 rows each come from a different policy, explain what the dimensions do and do not count.

Method: interpret the dimensions using the stated row definition. The first component gives 186 rows, and the second gives 5 columns. Thus nrow(claim_events) is 186, while ncol(claim_events) is 5.

Because one row represents one event, the row count represents 186 event records. It does not represent 186 distinct policies. The question states that 172 rows each come from a different policy and that the remaining 14 rows are repeat events from policies already represented. Therefore the number of distinct policies represented is 172, while the number of event rows is 186.

The count of five columns means there are five recorded variables in this data frame. It does not establish whether those are the five variables the analysis needs; that requires a separate check of the data specification.

Common mistake avoided: Treating every row as a unique policy would overstate the number of represented policies by 14. Dimension functions count rows, not distinct values of an identifier. The row count has meaning only when paired with the row’s intended unit.

R check: dim(claim_events) returns c(186, 5); nrow(claim_events) returns 186; ncol(claim_events) returns 5. These counts are consistent with 186 event records and five variables, not with 186 unique policies.

Worked Example: Interpreting a Data Frame with a Zero Dimension

An analyst creates two hypothetical data frames while preparing an extract. The first has four retained row positions but no variables. The second has no observations yet but has three defined variables. Determine the dimensions and explain why a zero count in one dimension does not force the other count to be zero.

Method: record rows and columns separately. For a data frame with four rows and zero columns, the dimension vector is c(4, 0). Therefore dim(empty_fields) returns c(4, 0), nrow(empty_fields) returns 4, and ncol(empty_fields) returns 0.

For a data frame with zero rows and three columns, the dimension vector is c(0, 3). Thus dim(empty_records) returns c(0, 3), nrow(empty_records) returns 0, and ncol(empty_records) returns 3.

The two results differ because the functions report the row and column counts independently. In the first case, rows remain even though there are no columns whose entries could be inspected. In the second, variables are defined even though no observations have been recorded. In either case, the ordered pair from dim() agrees with the two separate function results.

Common mistake avoided: Do not assume that a zero in one position makes the whole data frame empty. A data frame is empty of recorded cells when at least one dimension is zero, but its row count and column count remain distinct properties and should be reported separately.

R check: For empty_fields, the results are c(4, 0), 4, and 0. For empty_records, the results are c(0, 3), 0, and 3, in the order dim(), nrow(), and ncol().

A Practical Dimension-Checking Routine

A useful check is to compare the three results with one another and then compare them with the data’s intended design. This separates an R-level consistency check from a substantive check of the dataset. The first can be performed mechanically; the second requires knowing the observational unit and expected scope.

1
State the intended row unit.
Write down what one row is supposed to represent, such as one policy, one claim event, or one policy-month. Do not assume that a row is a unique person or entity unless the design says so.
2
Read both dimensions in order.
Use dim(data) and interpret its first value as rows and its second as columns. Keep the order explicit when documenting the result.
3
Cross-check each count.
Compare the first value with nrow(data) and the second with ncol(data). For a data frame, the corresponding values should agree because the functions report the same dimensions in combined and separate forms.
4
Compare with expectations, then investigate discrepancies.
Ask whether the observed counts match the intended population, extract period, and variable specification. A mismatch is a signal to investigate, not proof of a particular data error.

What Dimension Checks Can Establish

Dimensions can quickly detect some structural problems. If an extract is expected to contain 500 observations but nrow() returns 470, the discrepancy deserves attention. If a prepared data frame is supposed to have eight variables but ncol() returns seven, the object does not meet that stated expectation. In both cases, checking the count is useful before proceeding with analysis.

The result is still limited. A data frame can have the expected number of rows while containing duplicate records, the wrong records, or records drawn from the wrong period. It can have the expected number of columns while one column contains a different measurement from the one intended. Dimension functions do not inspect those content issues. They also do not establish that every row corresponds to a different unit when the row definition permits repeated units.

A sound interpretation therefore has two parts: report what R counted, then state what those counts mean under the dataset’s stated design. For example, “The data frame has 186 rows and five columns; because each row is an event, the 186 rows count events, not necessarily distinct policies.” That statement is more informative than “There are 186 policies.”

Common Traps

  • Reversing the order. In dim(data), rows come first and columns second. Read c(186, 5) as 186 rows and 5 columns.
  • Calling rows unique entities. nrow() counts records. Whether those records are unique people, policies, or events depends on the row definition.
  • Assuming expected dimensions prove correctness. Matching counts do not show that the included records or measured variables are appropriate.
  • Reasoning from column entries alone. A data frame can have rows and zero columns. Use nrow() or the first component of dim() to report rows directly.
  • Ignoring a zero dimension. A data frame can have rows but no columns, or columns but no rows. Report both values rather than describing both as zero.
Key takeaway: For a data frame, dim() reports rows followed by columns, while nrow() and ncol() report those counts separately. Check that the functions agree, then interpret the counts using the intended observational unit and population. The counts describe structure; they do not certify data quality or representativeness.

Check Your Understanding

For each problem, distinguish the dimensions reported by R from what those dimensions mean in context.

  1. A hypothetical monthly extract is intended to contain one row for each of 275 account-months and four variables. R reports dim(account_months) as c(268, 4). What do nrow() and ncol() return, and how many fewer rows are present than intended? (Answer: nrow() is 268, ncol() is 4, and the extract has 7 fewer rows than intended.)
  2. A hypothetical service log has dim(service_log) equal to c(94, 6). Each row is one service call, and callers may make multiple calls. What does the row count represent, and does it establish the number of distinct callers? (Answer: It represents 94 service-call records; it does not establish the number of distinct callers.)
  3. A data frame has 0 rows and 5 columns. State dim(), nrow(), and ncol() results in that order, and explain whether the data frame has any recorded observations. (Answer: c(0, 5), 0, and 5; it has no recorded observations.)
  4. A data frame has four retained rows and no columns. State the results of dim(), nrow(), and ncol(). Why is it incorrect to infer that there are no rows because there are no column entries? (Answer: c(4, 0), 4, and 0; row and column counts are separate dimensions, so zero columns does not imply zero rows.)
  5. A hypothetical extract is expected to contain 150 transaction records and three variables. R reports c(150, 3), but the design specifies that several transactions may belong to the same customer. What can be concluded about records and customers? (Answer: The data frame has 150 transaction rows and three columns; the number of distinct customers cannot be inferred from those dimensions.)
Clinical Biostats