Вопрос

This is a strange one. I'm trying to do more with vectorized code instead of loops. I know I can do this with loops, what I'm looking for is the vectorized way in R for speed. I have a table creatively named tbl which looks like this:

A ,B ,C  ,D
1 ,1 ,10 ,22
2 ,2 ,12 ,32
3 ,5 ,44 ,37

I want to repeat the values of C and D for the number of values between A and B. In this case there would be one instance of the first row, one instance of the second row and 3 repetitions of the third row. The goal is this:

C  ,D
10 ,22
12 ,32
44 ,37
44 ,37
44 ,37

What I have so far is this but it doesn't work:

rep(list(tbl[,c("C","D")]), (tbl["B"] - tbl["A"] + 1) )

It works if I iterate over the rows but I would rather do it in one pass as a vectorized function. I have a feeling the list(tbl[,c("C","D")]) is the part that is tripping up because it is not aware of which row it is working on. Any help or guidance is appreciated. If I'm going down the wrong rabbit hole please feel free to let me know. Thanks!

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

Решение

You're actually pretty close.

Try this instead:

tbl[rep(rownames(tbl), tbl[, "B"] - tbl[, "A"] + 1), c("C", "D")]
#      C  D
# 1   10 22
# 2   12 32
# 3   44 37
# 3.1 44 37
# 3.2 44 37

Другие советы

DF <- read.table(text="A ,B ,C  ,D
1 ,1 ,10 ,22
2 ,2 ,12 ,32
3 ,5 ,44 ,37", sep=",", header=TRUE)

DF[rep(seq_len(nrow(DF)), DF$B-DF$A+1), c("C", "D")]

#     C  D
#1   10 22
#2   12 32
#3   44 37
#3.1 44 37
#3.2 44 37
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top