R语言base包apply函数针对不同输入返回结果不一致问题求助
apply() Acts Weird With Lists of Varying Lengths in R Hey there, let's unpack why you're getting confusing results with apply() when working with your date lists. The core issue here is a common R pitfall: apply() is designed for matrices and arrays, not lists—and when you pass a list to it, R has to do some messy coercion that breaks your expected behavior.
Let's Break Down the Problem
When you feed a list into apply(), R first converts that list to a matrix using as.matrix(). For lists with elements of the same length, this works fine (it just turns each list element into a column or row). But when your list has elements of different lengths—like your empty beforedates2010 vector and longer vectors for other years—R has to pad shorter elements with NA values to match the length of the longest element.
For example, your befores list has a longest element of 7 items (from 2016). When converted to a matrix:
- The empty 2010 vector becomes a column of 7
NAs - The 3-item 2008/2014 vectors get padded with 4
NAs each - The 5-item 2012 vector gets padded with 2
NAs
When you run apply() on this matrix, you're operating on rows (if using MARGIN=1) or columns (if MARGIN=2) of this padded data—not your original list elements. That's why your results are inconsistent!
The Fix: Use List-Specific Functions
Instead of apply(), use lapply() or sapply()—these functions are built explicitly for handling lists, and they process each element individually without coercing everything into a matrix.
Let's use your code to demonstrate. First, let's properly define your list with named elements for clarity:
beforedates2008 = c('11/02', '11/03', '11/04') beforedates2010 = c() beforedates2012 = c('11/02', '11/03', '11/04', '11/05', '11/06') beforedates2014 = c('11/02', '11/03', '11/04') beforedates2016 = c('11/02', '11/03', '11/04', '11/05', '11/06', '11/07', '11/08') befores = list( "2008" = beforedates2008, "2010" = beforedates2010, "2012" = beforedates2012, "2014" = beforedates2014, "2016" = beforedates2016 )
Example 1: Count elements per list item
If you want to count how many dates are in each year's list, use lapply() (returns a list) or sapply() (simplifies to a vector):
# Using lapply (preserves list structure) lapply(befores, length) # $`2008` # [1] 3 # $`2010` # [1] 0 # $`2012` # [1] 5 # $`2014` # [1] 3 # $`2016` # [1] 7 # Using sapply (returns a clean vector) sapply(befores, length) # 2008 2010 2012 2014 2016 # 3 0 5 3 7
Example 2: Count occurrences of each date
If your goal is to count how many times each date appears in each year's list, lapply() with table() works perfectly:
lapply(befores, table) # $`2008` # # 11/02 11/03 11/04 # 1 1 1 # # $`2010` # < table of extent 0 > # # $`2012` # # 11/02 11/03 11/04 11/05 11/06 # 1 1 1 1 1 # ...
Key Takeaway
apply()= matrices/arrays onlylapply()/sapply()= lists of any length
By switching to the right tool for the job, you'll get consistent, predictable results that match your original data structure.
内容的提问来源于stack exchange,提问作者jaffjaff

