如何根据另一个查找 table/data 帧自动为一个数据帧插入值?
How to automatically interpolate values for one data frame based on another lookup table/data frame?
我有一个数据框和一个查找table。我想要的是比较 df_dat$value
和 df_lookup$threshold
。
如果 value
属于 threshold
范围,则在 df_dat
中创建一个新列 transfer
以便其值为
从 df_lookup
中的 transfer
列线性插值
library(dplyr)
df_lookup <- tribble(
~threshold, ~transfer,
0, 0,
100, 15,
200, 35
)
df_lookup
#> # A tibble: 3 x 2
#> threshold transfer
#> <dbl> <dbl>
#> 1 0 0
#> 2 100 15
#> 3 200 35
df_dat <- tribble(
~date, ~value,
"2009-01-01", 0,
"2009-01-02", 30,
"2009-01-06", 105,
"2009-01-09", 150
)
df_dat
#> # A tibble: 4 x 2
#> date value
#> <chr> <dbl>
#> 1 2009-01-01 0
#> 2 2009-01-02 30
#> 3 2009-01-06 105
#> 4 2009-01-09 150
我可以像这样手动完成,但想知道是否有基于 df_lookup
table 中的值的自动方法?谢谢。
df_dat %>%
mutate(transfer = case_when(value > 0 & value < 100 ~ 0 + (value - 0)*(15 - 0)/(100 - 0),
value >= 100 & value < 200 ~ 15 + (value - 100)*(35 - 15)/(200 - 100),
TRUE ~ 0)
)
#> # A tibble: 4 x 3
#> date value transfer
#> <chr> <dbl> <dbl>
#> 1 2009-01-01 0 0
#> 2 2009-01-02 30 4.5
#> 3 2009-01-06 105 16
#> 4 2009-01-09 150 25
您可以使用approx
df_dat %>% mutate(transfer = with(df_lookup, approx(threshold, transfer, value))$y)
## A tibble: 4 x 3
# date value transfer
# <chr> <dbl> <dbl>
#1 2009-01-01 0 0
#2 2009-01-02 30 4.5
#3 2009-01-06 105 16
#4 2009-01-09 150 25
使用 roll
的另一个选项:
df_lookup[, m := (transfer - shift(transfer, -1L)) / (threshold - shift(threshold, -1L))]
df_dat[, tx :=
df_lookup[df_dat, on=c("threshold"="value"), roll=Inf,
x.m * (i.value - x.threshold) + x.transfer]
]
数据:
library(data.table)
df_lookup <- fread("threshold, transfer
0, 0
100, 15
200, 35")
df_dat <- fread('date, value
"2009-01-01", 0
"2009-01-02", 30
"2009-01-06", 105
"2009-01-09", 150')
我有一个数据框和一个查找table。我想要的是比较 df_dat$value
和 df_lookup$threshold
。
如果 value
属于 threshold
范围,则在 df_dat
中创建一个新列 transfer
以便其值为
从 df_lookup
transfer
列线性插值
library(dplyr)
df_lookup <- tribble(
~threshold, ~transfer,
0, 0,
100, 15,
200, 35
)
df_lookup
#> # A tibble: 3 x 2
#> threshold transfer
#> <dbl> <dbl>
#> 1 0 0
#> 2 100 15
#> 3 200 35
df_dat <- tribble(
~date, ~value,
"2009-01-01", 0,
"2009-01-02", 30,
"2009-01-06", 105,
"2009-01-09", 150
)
df_dat
#> # A tibble: 4 x 2
#> date value
#> <chr> <dbl>
#> 1 2009-01-01 0
#> 2 2009-01-02 30
#> 3 2009-01-06 105
#> 4 2009-01-09 150
我可以像这样手动完成,但想知道是否有基于 df_lookup
table 中的值的自动方法?谢谢。
df_dat %>%
mutate(transfer = case_when(value > 0 & value < 100 ~ 0 + (value - 0)*(15 - 0)/(100 - 0),
value >= 100 & value < 200 ~ 15 + (value - 100)*(35 - 15)/(200 - 100),
TRUE ~ 0)
)
#> # A tibble: 4 x 3
#> date value transfer
#> <chr> <dbl> <dbl>
#> 1 2009-01-01 0 0
#> 2 2009-01-02 30 4.5
#> 3 2009-01-06 105 16
#> 4 2009-01-09 150 25
您可以使用approx
df_dat %>% mutate(transfer = with(df_lookup, approx(threshold, transfer, value))$y)
## A tibble: 4 x 3
# date value transfer
# <chr> <dbl> <dbl>
#1 2009-01-01 0 0
#2 2009-01-02 30 4.5
#3 2009-01-06 105 16
#4 2009-01-09 150 25
使用 roll
的另一个选项:
df_lookup[, m := (transfer - shift(transfer, -1L)) / (threshold - shift(threshold, -1L))]
df_dat[, tx :=
df_lookup[df_dat, on=c("threshold"="value"), roll=Inf,
x.m * (i.value - x.threshold) + x.transfer]
]
数据:
library(data.table)
df_lookup <- fread("threshold, transfer
0, 0
100, 15
200, 35")
df_dat <- fread('date, value
"2009-01-01", 0
"2009-01-02", 30
"2009-01-06", 105
"2009-01-09", 150')