如何在R语言中对向量进行连续重复元素的特定索引处理
How to Index Consecutive Duplicate Elements in R
First, let's break down why your current code isn't working as expected:
- The condition
x[-length(x)] == x[-1]compares all adjacent elements at once, returning a logical vector instead of checking each position individually. - Trying to assign
y[i] = y[i+1]is backwards (sincey[i+1]hasn't been populated yet when you're at positioni), and theelse nextmeans you're skipping assignments for non-consecutive elements entirely. - Your function also doesn't return the
yvector at the end, so you'd never get any output even if the logic worked!
The Simplest Solution: Use rle()
R has a built-in function rle() (Run Length Encoding) that's made exactly for this kind of task—it automatically groups consecutive duplicate values and records their lengths. Here's how to use it to get your desired index vector:
svector <- function(x) { # Get run-length encoding of the input vector run_info <- rle(x) # Repeat each index (1, 2, 3...) according to the length of each run rep(seq_along(run_info$lengths), times = run_info$lengths) } # Test it with your example x <- c(1,1,2,3,1,1,2,3) svector(x) # Output: [1] 1 1 2 3 4 4 5 6
How this works:
rle(x)returns a list with two key components:lengths: A vector of the lengths of each consecutive run (for yourx, this isc(2, 1, 1, 2, 1, 1)).values: The unique value for each run (c(1, 2, 3, 1, 2, 3)).
seq_along(run_info$lengths)creates a sequence of indices from 1 to the number of runs (so1:6here).rep(...)repeats each index exactly the number of times the corresponding run lasts, giving you the final indexed vector.
A Loop-Based Alternative (For Step-by-Step Understanding)
If you prefer a manual loop to see the underlying logic, here's a corrected version of your initial approach:
svector_loop <- function(x) { # Handle empty input case if (length(x) == 0) return(numeric(0)) # Initialize output vector with the same length as x y <- numeric(length(x)) current_index <- 1 y[1] <- current_index # First element always starts at index 1 # Iterate from the second element onwards for (i in 2:length(x)) { if (x[i] == x[i-1]) { # Same as previous element: keep the current index y[i] <- current_index } else { # Different from previous: increment index and assign current_index <- current_index + 1 y[i] <- current_index } } return(y) } svector_loop(x) # Output: [1] 1 1 2 3 4 4 5 6
This loop tracks the current index, only incrementing it when we hit a new value that doesn't match the previous element.
内容的提问来源于stack exchange,提问作者blazedosan002
相关产品推荐
相关产品推荐

