Quick summary
Summarize this blog with AI
Sum selected measurements within each row
rowSums() produces one total per row. Select the measurements that should contribute before you call it: an identifier or an already calculated total may be numeric but should not automatically be included. The examples below use base R 4.5.1 and a fictional store-by-day table.
Start with explicit numeric columns
sales <- data.frame(
store_id = c("A", "B", "C", "D"),
monday = c(100, 250, NA, NA),
tuesday = c(200, 300, 90, NA),
wednesday = c(50, 400, 110, NA)
)
measurement_columns <- c("monday", "tuesday", "wednesday")
amounts <- as.matrix(sales[measurement_columns])
stopifnot(is.numeric(amounts))
totals <- rowSums(amounts)
print(totals) # 350 950 NA NA
stopifnot(identical(totals, c(350, 950, NA_real_, NA_real_)))
Each result corresponds to the same row in sales. Row C has a missing Monday value, so its complete three-day total is unknown. Row D has no recorded measurements. A row total does not group repeated store IDs; each row is processed independently.
Separate an observed subtotal from a complete total
observed_days <- rowSums(!is.na(amounts))
observed_subtotal <- rowSums(amounts, na.rm = TRUE)
print(observed_subtotal) # 350 950 200 0
observed_subtotal[observed_days == 0] <- NA_real_
result <- data.frame(store_id = sales$store_id, observed_days,
observed_subtotal, complete_total = totals)
print(result)
stopifnot(identical(observed_days, c(3, 3, 2, 0)))
stopifnot(identical(observed_subtotal, c(350, 950, 200, NA_real_)))
With na.rm = TRUE, an all-missing row sums to zero because no values remain. The explicit adjustment records “no observed sales data” as missing instead of silently treating it as zero sales. Row C's observed subtotal remains 200, but its complete total remains unknown. Name and report those quantities differently.
Count qualifying cells versus sum qualifying amounts
above_200 <- amounts > 200
qualifying_count <- rowSums(above_200, na.rm = TRUE)
qualifying_amounts <- amounts
qualifying_amounts[!is.na(amounts) & amounts <= 200] <- 0
qualifying_subtotal <- rowSums(qualifying_amounts, na.rm = TRUE)
qualifying_subtotal[observed_days == 0] <- NA_real_
print(qualifying_count) # 0 3 0 0
print(qualifying_subtotal) # 0 950 0 NA
stopifnot(identical(qualifying_count, c(0, 3, 0, 0)))
stopifnot(identical(qualifying_subtotal, c(0, 950, 0, NA_real_)))
rowSums(amounts > 200) counts TRUE values; it does not add money. To add qualifying amounts, keep those numeric values and replace known nonqualifying amounts with zero. The examples omit missing observations, so their counts and subtotals concern observed cells only. Missing cells could change the complete qualifying count and total.
Check shape and preserve the chosen columns
# Keep a matrix when selecting a single column.
monday <- amounts[, "monday", drop = FALSE]
stopifnot(identical(dim(monday), c(4L, 1L)))
stopifnot(isTRUE(all.equal(rowSums(monday), sales$monday)))
stopifnot(length(rowSums(amounts[FALSE, , drop = FALSE])) == 0)
stopifnot(identical(rowSums(matrix(numeric(0), nrow = 2, ncol = 0)), c(0, 0)))
sales$total <- totals
stopifnot(identical(rowSums(as.matrix(sales[measurement_columns])), totals))
An empty row set returns an empty result; a matrix with zero columns returns a zero for each row. In a business calculation, accidentally selecting no measurement columns should normally fail validation rather than be accepted as zero. Keep the explicit column list when you rerun the calculation so that the newly added total is not summed again.
Use colSums() for one total per day and sum() for one grand total. See sum, row totals and column totals in R for a direct comparison. Do not convert arbitrary text columns to numeric and ignore the resulting missing values merely to make a total run.