Вопрос

Given x and y I wish to create the desired.result below:

x <- 1:10

y <- c(2:4,6:7,8:9)

desired.result <- c(1,2,2,2,3,4,4,5,5,6)

where, in effect, each sequence in y is replaced in x by the the first element in the sequence in y and then the elements of the new x are numbered.

The intermediate step for x would be:

x.intermediate <- c(1,2,2,2,5,6,6,8,8,10)

Below is code that does this. However, the code is not general and is overly complex:

x <- 1:10

y <- list(c(2:4),(6:7),(8:9))

unique.x <- 1:(length(x[-unlist(y)]) + length(y))

y1 <- rep(min(unlist(y[1])), length(unlist(y[1])))
y2 <- rep(min(unlist(y[2])), length(unlist(y[2])))
y3 <- rep(min(unlist(y[3])), length(unlist(y[3])))

new.x <- x

new.x[unlist(y[1])] <- y1
new.x[unlist(y[2])] <- y2
new.x[unlist(y[3])] <- y3

rep(unique.x, rle(new.x)$lengths)

 [1] 1 2 2 2 3 4 4 5 5 6

Below is my attempt to generalize the code. However, I am stuck on the second lapply.

x <- 1:10

y <- list(c(2:4),(6:7),(8:9))

unique.x <- 1:(length(x[-unlist(y)]) + length(y))

y2 <- lapply(y, function(i) rep(min(i), length(i)))

new.x <- x

lapply(y2, function(i) new.x[i[1]:(i[1]-1+length(i))] = i)

rep(unique.x, rle(new.x)$lengths)

Thank you for any advice. I suspect there is a much simpler solution I am overlooking. I prefer a solution in base R.

Это было полезно?

Решение

A solution like this should work:

x <- 1:10
y <- list(c(2:4),(6:7),(8:9))

x[unlist(y)]<-rep(sapply(y,'[',1),lapply(y,length))

rep(1:length(rle(x)$lengths), rle(x)$lengths)

## [1] 1 2 2 2 3 4 4 5 5 6
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top