从具有间隔的 table 中获取特定于位置的值

Obtain position-specific value from a table with intervals

我有一个 table 有 3 列,指示每个间隔的开始和结束,以及间隔内所有位置的比率。

| Start    | End            | Rate  |
| -------- | -------------- | ----- |
| 1        | 2              | 2.0   |
| 3        | 5              | 4.2   |
| 6        | 9              | 1.8   |
| 10       | 16             | 1.2   |

我需要对其进行扩展,以获得一个 table 来指示每个特定位置的费率,例如:

| Position | Rate           |
| -------- | -------------- |
| 1        | 2.0            |
| 2        | 2.0            |
| 3        | 4.2            |
| 4        | 4.2            |
| 5        | 4.2            |
| 6        | 1.8            |
| 7        | 1.8            |
| 8        | 1.8            |
| 9        | 1.8            |
| 10       | 1.2            |

等等。

由于仓位数量多(3000万),想知道有没有一种快速的方法可以从范围到特定仓位进行转换,并为每个仓位分配正确的费率。一个不包含无限 if 循环的人,该循环检查某个位置对每个间隔的归属。

有没有办法将原始 table 转换为类似于第二个的东西?

在此先感谢您的帮助,对于没有提供任何初步代码表示歉意。我真的不知道如何处理这个问题。

这个方法怎么样?

我没有for循环就做到了:

df =matrix( c(1,2,2,3,5,4.2,6,9,1.8,10,16,1.2), byrow = T, ncol=3)

g= function(e){
  x= rep(e[3], (e[2]-e[1]+1))
return(x)
}
res = cbind(1:df[nrow(df),2],as.numeric(unlist(apply(df,1,g))))
colnames(res)=c('position' ,'rate')

输出:

     position rate
 [1,]        1  2.0
 [2,]        2  2.0
 [3,]        3  4.2
 [4,]        4  4.2
 [5,]        5  4.2
 [6,]        6  1.8
 [7,]        7  1.8
 [8,]        8  1.8
 [9,]        9  1.8
[10,]       10  1.2
[11,]       11  1.2
[12,]       12  1.2
[13,]       13  1.2
[14,]       14  1.2
[15,]       15  1.2
[16,]       16  1.2

您可以使用 map2StartEnd 列之间创建序列。

library(tidyverse)

df %>%
  transmute(Position = map2(Start, End, seq), Rate) %>%
  unnest(Position)

#   Position  Rate
#      <int> <dbl>
# 1        1   2  
# 2        2   2  
# 3        3   4.2
# 4        4   4.2
# 5        5   4.2
# 6        6   1.8
# 7        7   1.8
# 8        8   1.8
# 9        9   1.8
#10       10   1.2
#11       11   1.2
#12       12   1.2
#13       13   1.2
#14       14   1.2
#15       15   1.2
#16       16   1.2

一个data.table选项

setDT(df)[, .(Position = Start:End, Rate = Rate), .(id = 1:nrow(df))]

给予

    id Position Rate
 1:  1        1  2.0
 2:  1        2  2.0
 3:  2        3  4.2
 4:  2        4  4.2
 5:  2        5  4.2
 6:  3        6  1.8
 7:  3        7  1.8
 8:  3        8  1.8
 9:  3        9  1.8
10:  4       10  1.2
11:  4       11  1.2
12:  4       12  1.2
13:  4       13  1.2
14:  4       14  1.2
15:  4       15  1.2
16:  4       16  1.2

dplyr选项使用unnest

df %>%
  rowwise() %>%
  mutate(Positions = list(Start:End)) %>%
  unnest(Positions) %>%
  select(Positions, Rate)

这给出了

# A tibble: 16 x 2
   Positions  Rate
       <int> <dbl>
 1         1   2
 2         2   2
 3         3   4.2
 4         4   4.2
 5         5   4.2
 6         6   1.8
 7         7   1.8
 8         8   1.8
 9         9   1.8
10        10   1.2
11        11   1.2
12        12   1.2
13        13   1.2
14        14   1.2
15        15   1.2
16        16   1.2`

数据

> dput(df)
structure(list(Start = c(1, 3, 6, 10), End = c(2, 5, 9, 16),
    Rate = c(2, 4.2, 1.8, 1.2)), class = "data.frame", row.names = c(NA,
-4L))

我们可以使用 rowwisedplyr

中的 summarise
library(dplyr)
df %>%
  rowwise %>%
  summarise(Position = Start:End, Rate, .groups = 'drop')

-输出

# A tibble: 16 x 2
   Position  Rate
      <int> <dbl>
 1        1   2  
 2        2   2  
 3        3   4.2
 4        4   4.2
 5        5   4.2
 6        6   1.8
 7        7   1.8
 8        8   1.8
 9        9   1.8
10       10   1.2
11       11   1.2
12       12   1.2
13       13   1.2
14       14   1.2
15       15   1.2
16       16   1.2

数据

df <- structure(list(Start = c(1, 3, 6, 10), End = c(2, 5, 9, 16), 
    Rate = c(2, 4.2, 1.8, 1.2)), class = "data.frame", row.names = c(NA, 
-4L))