Handling missing values (drop_na, fill) in R Programming - Time & Space Complexity
When working with data, we often need to handle missing values. This topic looks at how the time to clean data grows as the data size increases.
We want to know how long it takes to remove or fill missing values as the data gets bigger.
Analyze the time complexity of the following code snippet.
library(dplyr)
library(tidyr)
data <- tibble(
x = c(1, NA, 3, NA, 5),
y = c(NA, 2, 3, 4, NA)
)
# Remove rows with any NA
clean_data <- drop_na(data)
# Fill NA with zero
filled_data <- data %>% mutate(across(everything(), ~replace_na(.x, 0)))
This code removes rows with missing values and fills missing values with zero in a data frame.
- Primary operation: Checking each element in the data frame for missing values.
- How many times: Once for each element in the data (rows x columns).
As the number of rows grows, the program checks more elements to find missing values.
| Input Size (rows x columns) | Approx. Operations |
|---|---|
| 10 x 2 = 20 | About 20 checks |
| 100 x 2 = 200 | About 200 checks |
| 1000 x 2 = 2000 | About 2000 checks |
Pattern observation: The number of checks grows directly with the number of elements in the data.
Time Complexity: O(n)
This means the time to handle missing values grows in a straight line as the data size grows.
[X] Wrong: "Handling missing values takes the same time no matter how big the data is."
[OK] Correct: The program must check every element, so bigger data means more work and more time.
Understanding how data cleaning time grows helps you write efficient code and explain your choices clearly in real projects.
"What if we only fill missing values in one column instead of all columns? How would the time complexity change?"
Practice
drop_na() function do in R's tidyr package?Solution
Step 1: Understand the purpose of
The function is designed to remove rows that have missing (NA) values in specified columns or in the entire data frame if no columns are specified.drop_na()Step 2: Compare with other options
Options A and C describe filling missing values, which is done byfill()or other functions, notdrop_na(). Sorts the data frame by missing values. sorts the data frame by missing values, which is unrelated.Final Answer:
Removes rows that contain missing values in specified columns. -> Option CQuick Check:
drop_na()removes rows with NA [OK]
- Confusing drop_na() with fill()
- Thinking drop_na() fills missing values
- Assuming drop_na() sorts data
df using the fill() function from tidyr for the column score?Solution
Step 1: Recall the pipe operator usage
Thefill()function is typically used with the pipe operator%>%to pass the data frame as the first argument.Step 2: Check the argument order and syntax
df %>% fill(score, .direction = "down") correctly usesdf %>% fill(score, .direction = "down"). Options B and C have wrong syntax or argument order. df.fill(score, direction = "down") uses incorrect syntax not valid in R.Final Answer:
df %>% fill(score, .direction = "down") -> Option DQuick Check:
Use pipe %>% before fill() with column name [OK]
- Passing data frame as second argument
- Using dot direction without dot prefix
- Using Python-like method syntax
df below:df <- data.frame(id = 1:5, score = c(10, NA, 15, NA, 20)) df_filled <- df %>% fill(score, .direction = "down") print(df_filled)
What will be the output of
print(df_filled)?Solution
Step 1: Understand fill() with .direction = "down"
The function fills missing values by copying the last known non-NA value downward to replace NA values.Step 2: Apply fill() to the data
Row 2's NA is replaced by 10 (from row 1), row 4's NA is replaced by 15 (from row 3). Other values remain unchanged.Final Answer:
id score 1 1 10 2 2 10 3 3 15 4 4 15 5 5 20 -> Option AQuick Check:
fill() copies last known value down [OK]
- Assuming fill() replaces NA with next value
- Thinking fill() leaves NA unchanged
- Confusing fill() direction
library(tidyr) df <- data.frame(x = c(1, NA, 3), y = c(NA, 2, 3)) df_clean <- drop_na(df, x) print(df_clean)
What is the output of
print(df_clean)?Solution
Step 1: Understand drop_na(df, x)
This removes rows where columnxhas NA values. Row 2 has NA inx, so it is removed.Step 2: Identify remaining rows
Rows 1 and 3 remain. Row 1 hasx=1,y=NA. Row 3 hasx=3,y=3.Final Answer:
x y 1 1 NA 3 3 3 -> Option AQuick Check:
drop_na(df, x) removes rows with NA in x [OK]
- Removing rows with NA in all columns instead of specified
- Confusing drop_na() with fill()
- Expecting NA values to be replaced
df with columns time and temperature, where some temperature values are missing (NA). You want to fill missing temperatures by carrying the last known temperature forward, but only within each day (grouped by time). Which code correctly achieves this?Solution
Step 1: Group data by
Grouping bytimetimeensures fill() works within each day separately.Step 2: Use fill() with .direction = "down"
Filling downward copies last known temperature forward within each group.Step 3: Check other options
df %>% fill(temperature, .direction = "down") %>% group_by(time) fills before grouping, so fill applies to whole data ignoring groups. df %>% fill(temperature, .direction = "up") %>% group_by(time) fills upward, which is opposite of requirement. df %>% group_by(time) %>% drop_na(temperature) drops rows with NA instead of filling.Final Answer:
df %>% group_by(time) %>% fill(temperature, .direction = "down") -> Option BQuick Check:
Group then fill down to fill within groups [OK]
- Filling before grouping
- Using fill direction up instead of down
- Dropping rows instead of filling
Ready to prove it?
Pass the test and this pattern moves unknown
