Dplyr R报错:missing value where TRUE/FALSE needed 序列排序咨询
Hey Betsy, let's work through that "missing value where TRUE/FALSE needed" error you're hitting with your dplyr code—this is a super common gotcha when building conditional counters in grouped data. Here's how to diagnose and fix it:
1. You’ve got NA values sneaking into your conditions
This error almost always pops up because one of your conditional checks (date difference, mycheckfunc() output, or row index) is returning NA, which R can’t interpret as TRUE/FALSE for ifelse(). Let’s track them down:
- Check date column & date differences: First, make sure your date column has no missing values, and that the date difference calculation doesn’t produce NAs. Add a debug step to inspect this:
dt %>% group_by(obsID) %>% arrange(row_index) %>% mutate(date_diff = date_col - lag(date_col)) %>% # Adjust based on your date order logic filter(is.na(date_diff)) - Validate
mycheckfunc()output: Your custom function might be returning NAs for some rows. Test it in isolation to see:
If you find NAs here, updatedt %>% mutate(check_result = mycheckfunc(col1, col2, col3)) %>% # Pass your actual arguments filter(is.na(check_result))mycheckfunc()to handle edge cases (e.g., addis.na()checks inside the function) or usedplyr::coalesce()to convert NAs to a default TRUE/FALSE value.
2. Nested ifelse() is hard to debug—switch to case_when()
Nested ifelse() chains are messy and make it easy to miss NA handling. case_when() is more readable and lets you explicitly account for NA scenarios. Here’s how to refactor your code:
dt <- dt %>% group_by(obsID) %>% arrange(row_index) %>% mutate( # Calculate intermediate variables first for debugging date_diff = date_col - lag(date_col), # Adjust direction to match your needs check_pass = mycheckfunc(col1, col2, col3), # Build the order counter with explicit NA handling order = case_when( row_index == 1 ~ 1L, # Start counter at 1 for first row in group # Only proceed if date_diff is valid AND meets your threshold AND check passes !is.na(date_diff) & date_diff > 7 & check_pass ~ lag(order) + 1L, # Replace 7 with your actual threshold # Reset counter if conditions fail !is.na(date_diff) & !(date_diff > 7) | !check_pass ~ 1L, # Catch-all for remaining NA cases TRUE ~ NA_integer_ ) )
Note: I replaced £ with 7 as a placeholder—make sure to swap in your actual date difference threshold (e.g., 30 for 30 days).
3. Double-check your grouping & ordering
If your row_index has missing values or isn’t sorting rows correctly within each obsID group, your date difference and counter logic will break. Verify with:
dt %>% group_by(obsID) %>% arrange(row_index) %>% print(n = 20) # Inspect the first 20 rows of each group
Also confirm row_index has no NAs:
dt %>% filter(is.na(row_index))
4. Debug step-by-step
Don’t try to build the entire mutate() call at once. Break it into smaller chunks to isolate where the NA is coming from:
- First, confirm grouping and ordering work as expected.
- Add the date difference and
mycheckfunc()output columns separately. - Only once those are clean (no NAs where you don’t expect them) add the
ordercounter logic.
内容的提问来源于stack exchange,提问作者Betsy

