值之间的线性插值
Linear interpolation between values
我有一个 table t,其中 x 和 y 值间隔在 x 的每 10 个整数之间(value
列),例如:
value -20 -10 0 24 40 55
1 100 41700 41700 41700 41700 41800 41700
2 90 40200 40600 40700 40800 40800 40800
3 80 39200 39700 39800 40000 40000 39900
4 70 38200 38800 38800 39000 39100 39000
5 60 37200 37800 37900 38000 38200 38200
6 50 36200 36700 36900 37000 37000 37000
7 40 35400 35900 36200 36300 36300 36400
8 30 34600 35300 35600 35800 35800 35900
9 20 33700 34600 34800 35200 35100 35100
10 10 31600 33700 33800 34000 33900 33900
11 0 30000 30000 26500 30700 30100 30100
现在,table 是 11 行 x 7 列。我的目标是为 0 到 100 之间的每个整数在所有 6 列中线性插入值,以便最后的 table 是 101 行 x 7 列。
我可以使用以下方法分别对每一列进行插值:
x <- t$value
y <- t$`-20`
plot(x, y, main = "-20 mv", xlab = "soc", ylab = "temp", pch = 20)
points(approx(x, y, xout = 0:100), col ="blue", pch = 1)
任何人都可以建议使用 dplyr
或 data.table
或基于 R 的一些命令将其应用于整个 table 的更快方法吗?
数据:
dput(t)
structure(list(value = c(100L, 90L, 80L, 70L, 60L, 50L, 40L,
30L, 20L, 10L, 0L), `-20` = c(41700L, 40200L, 39200L, 38200L,
37200L, 36200L, 35400L, 34600L, 33700L, 31600L, 30000L), `-10` = c(41700L,
40600L, 39700L, 38800L, 37800L, 36700L, 35900L, 35300L, 34600L,
33700L, 30000L), `0` = c(41700L, 40700L, 39800L, 38800L, 37900L,
36900L, 36200L, 35600L, 34800L, 33800L, 26500L), `24` = c(41700L,
40800L, 40000L, 39000L, 38000L, 37000L, 36300L, 35800L, 35200L,
34000L, 30700L), `40` = c(41800L, 40800L, 40000L, 39100L, 38200L,
37000L, 36300L, 35800L, 35100L, 33900L, 30100L), `55` = c(41700L,
40800L, 39900L, 39000L, 38200L, 37000L, 36400L, 35900L, 35100L,
33900L, 30100L)), class = "data.frame", row.names = c(NA, -11L
))
使用 dplyr
你可以:
library(dplyr)
t %>% summarise(across(everything(), ~approx(value, ., xout=0:100)$y))
value -20 -10 0 24 40 55
1 0 30000 30000 26500 30700 30100 30100
2 1 30160 30370 27230 31030 30480 30480
3 2 30320 30740 27960 31360 30860 30860
4 3 30480 31110 28690 31690 31240 31240
5 4 30640 31480 29420 32020 31620 31620
...
95 94 40800 41040 41100 41160 41200 41160
96 95 40950 41150 41200 41250 41300 41250
97 96 41100 41260 41300 41340 41400 41340
98 97 41250 41370 41400 41430 41500 41430
99 98 41400 41480 41500 41520 41600 41520
100 99 41550 41590 41600 41610 41700 41610
101 100 41700 41700 41700 41700 41800 41700
或以 R 为基数:
do.call(cbind, lapply(t, function(y) {approx(t$value, y, xout=0:100)$y}))
我有一种手动 R 基础解决方案:
sapply(df[,-1],function(col){
c(col[1],lapply(c(diff(col))/10,function(x) x*1:10) %>%
unlist() + rep(col[-11],each = 10) )
})
不完全确定它是否更快
-20 -10 0 24 40 55
[1,] 41700 41700 41700 41700 41800 41700
[2,] 41550 41590 41600 41610 41700 41610
[3,] 41400 41480 41500 41520 41600 41520
[4,] 41250 41370 41400 41430 41500 41430
[5,] 41100 41260 41300 41340 41400 41340
[6,] 40950 41150 41200 41250 41300 41250
[7,] 40800 41040 41100 41160 41200 41160
[8,] 40650 40930 41000 41070 41100 41070
[9,] 40500 40820 40900 40980 41000 40980
[10,] 40350 40710 40800 40890 40900 40890
[11,] 40200 40600 40700 40800 40800 40800
[12,] 40100 40510 40610 40720 40720 40710
....
[90,] 31810 33790 33900 34120 34020 34020
[91,] 31600 33700 33800 34000 33900 33900
[92,] 31440 33330 33070 33670 33520 33520
[93,] 31280 32960 32340 33340 33140 33140
[94,] 31120 32590 31610 33010 32760 32760
[95,] 30960 32220 30880 32680 32380 32380
[96,] 30800 31850 30150 32350 32000 32000
[97,] 30640 31480 29420 32020 31620 31620
[98,] 30480 31110 28690 31690 31240 31240
[99,] 30320 30740 27960 31360 30860 30860
[100,] 30160 30370 27230 31030 30480 30480
[101,] 30000 30000 26500 30700 30100 30100
这是一个 data.table
方法,其原理与 dplyr
方法相似:
library(data.table)
dt = as.data.table(t)
dt[, lapply(.SD, function(y) approx(value, y, xout = 0:100)[['y']])]
我有一个 table t,其中 x 和 y 值间隔在 x 的每 10 个整数之间(value
列),例如:
value -20 -10 0 24 40 55
1 100 41700 41700 41700 41700 41800 41700
2 90 40200 40600 40700 40800 40800 40800
3 80 39200 39700 39800 40000 40000 39900
4 70 38200 38800 38800 39000 39100 39000
5 60 37200 37800 37900 38000 38200 38200
6 50 36200 36700 36900 37000 37000 37000
7 40 35400 35900 36200 36300 36300 36400
8 30 34600 35300 35600 35800 35800 35900
9 20 33700 34600 34800 35200 35100 35100
10 10 31600 33700 33800 34000 33900 33900
11 0 30000 30000 26500 30700 30100 30100
现在,table 是 11 行 x 7 列。我的目标是为 0 到 100 之间的每个整数在所有 6 列中线性插入值,以便最后的 table 是 101 行 x 7 列。
我可以使用以下方法分别对每一列进行插值:
x <- t$value
y <- t$`-20`
plot(x, y, main = "-20 mv", xlab = "soc", ylab = "temp", pch = 20)
points(approx(x, y, xout = 0:100), col ="blue", pch = 1)
任何人都可以建议使用 dplyr
或 data.table
或基于 R 的一些命令将其应用于整个 table 的更快方法吗?
数据:
dput(t)
structure(list(value = c(100L, 90L, 80L, 70L, 60L, 50L, 40L,
30L, 20L, 10L, 0L), `-20` = c(41700L, 40200L, 39200L, 38200L,
37200L, 36200L, 35400L, 34600L, 33700L, 31600L, 30000L), `-10` = c(41700L,
40600L, 39700L, 38800L, 37800L, 36700L, 35900L, 35300L, 34600L,
33700L, 30000L), `0` = c(41700L, 40700L, 39800L, 38800L, 37900L,
36900L, 36200L, 35600L, 34800L, 33800L, 26500L), `24` = c(41700L,
40800L, 40000L, 39000L, 38000L, 37000L, 36300L, 35800L, 35200L,
34000L, 30700L), `40` = c(41800L, 40800L, 40000L, 39100L, 38200L,
37000L, 36300L, 35800L, 35100L, 33900L, 30100L), `55` = c(41700L,
40800L, 39900L, 39000L, 38200L, 37000L, 36400L, 35900L, 35100L,
33900L, 30100L)), class = "data.frame", row.names = c(NA, -11L
))
使用 dplyr
你可以:
library(dplyr)
t %>% summarise(across(everything(), ~approx(value, ., xout=0:100)$y))
value -20 -10 0 24 40 55 1 0 30000 30000 26500 30700 30100 30100 2 1 30160 30370 27230 31030 30480 30480 3 2 30320 30740 27960 31360 30860 30860 4 3 30480 31110 28690 31690 31240 31240 5 4 30640 31480 29420 32020 31620 31620 ... 95 94 40800 41040 41100 41160 41200 41160 96 95 40950 41150 41200 41250 41300 41250 97 96 41100 41260 41300 41340 41400 41340 98 97 41250 41370 41400 41430 41500 41430 99 98 41400 41480 41500 41520 41600 41520 100 99 41550 41590 41600 41610 41700 41610 101 100 41700 41700 41700 41700 41800 41700
或以 R 为基数:
do.call(cbind, lapply(t, function(y) {approx(t$value, y, xout=0:100)$y}))
我有一种手动 R 基础解决方案:
sapply(df[,-1],function(col){
c(col[1],lapply(c(diff(col))/10,function(x) x*1:10) %>%
unlist() + rep(col[-11],each = 10) )
})
不完全确定它是否更快
-20 -10 0 24 40 55
[1,] 41700 41700 41700 41700 41800 41700
[2,] 41550 41590 41600 41610 41700 41610
[3,] 41400 41480 41500 41520 41600 41520
[4,] 41250 41370 41400 41430 41500 41430
[5,] 41100 41260 41300 41340 41400 41340
[6,] 40950 41150 41200 41250 41300 41250
[7,] 40800 41040 41100 41160 41200 41160
[8,] 40650 40930 41000 41070 41100 41070
[9,] 40500 40820 40900 40980 41000 40980
[10,] 40350 40710 40800 40890 40900 40890
[11,] 40200 40600 40700 40800 40800 40800
[12,] 40100 40510 40610 40720 40720 40710
....
[90,] 31810 33790 33900 34120 34020 34020
[91,] 31600 33700 33800 34000 33900 33900
[92,] 31440 33330 33070 33670 33520 33520
[93,] 31280 32960 32340 33340 33140 33140
[94,] 31120 32590 31610 33010 32760 32760
[95,] 30960 32220 30880 32680 32380 32380
[96,] 30800 31850 30150 32350 32000 32000
[97,] 30640 31480 29420 32020 31620 31620
[98,] 30480 31110 28690 31690 31240 31240
[99,] 30320 30740 27960 31360 30860 30860
[100,] 30160 30370 27230 31030 30480 30480
[101,] 30000 30000 26500 30700 30100 30100
这是一个 data.table
方法,其原理与 dplyr
方法相似:
library(data.table)
dt = as.data.table(t)
dt[, lapply(.SD, function(y) approx(value, y, xout = 0:100)[['y']])]