存在 N/A 时计算差异
Calculating difference when N/A's are present
我有一个 table(如下所列),我们在其中测量了一口井的温度。不幸的是(主要是由于天气)井中的水并不总是可以测量的,所以我们有 NA 的持久性。
Date Temp(C)
09-22 14
09-29 19.6
10-15 NA
10-28 11
11-06 NA
11-21 8
12-13 6
所以我想做的是创建一个新列来计算 Delta T 或温度从一个采样日期到下一个采样日期的变化,等等。如果有 NA,我想避免它并使用最后采样的温度进行计算。但我不知道如何编写该代码。
是这样的吗?
df$TempDiff <- c(NA_real_, diff(zoo::na.locf(df$`Temp(C)`)))
na.locf
表示用最近的 non-NA 替换 NA
。
输出看起来像这样
# A tibble: 7 x 3
Date `Temp(C)` TempDiff
<chr> <dbl> <dbl>
1 09-22 14 NA
2 09-29 19.6 5.6
3 10-15 NA 0
4 10-28 11 -8.6
5 11-06 NA 0
6 11-21 8 -3
7 12-13 6 -2
分组进行
df <- dplyr::group_by(df, Well)
dplyr::mutate(df, TempDiff = c(NA_real_, diff(zoo::na.locf(`Temp(C)`))))
输出
# A tibble: 7 x 4
# Groups: Well [2]
Date `Temp(C)` Well TempDiff
<chr> <dbl> <dbl> <dbl>
1 09-22 14 1 NA
2 09-29 19.6 1 5.6
3 10-15 NA 1 0
4 10-28 11 2 NA
5 11-06 NA 2 0
6 11-21 8 2 -3
7 12-13 6 2 -2
作为 zoo::na.locf
的替代方案,我们可以使用 tidyr 包中的 fill
> library(dplyr)
> library(tidyr)
> df %>%
fill(`Temp(C)`) %>%
mutate(Temp2 = c(NA, diff(`Temp(C)`)))
Date Temp(C) Temp2
1 09-22 14.0 NA
2 09-29 19.6 5.6
3 10-15 19.6 0.0
4 10-28 11.0 -8.6
5 11-06 11.0 0.0
6 11-21 8.0 -3.0
7 12-13 6.0 -2.0
一个data.table
单行
library( data.table )
setDT(mydata)[ !is.na( Temp ), delta := Temp - shift(Temp, type = "lag")]
# Date Temp delta
# 1: 09-22 14.0 NA
# 2: 09-29 19.6 5.6
# 3: 10-15 NA NA
# 4: 10-28 11.0 -8.6
# 5: 11-06 NA NA
# 6: 11-21 8.0 -3.0
# 7: 12-13 6.0 -2.0
如果您需要百分比:
> t %>% filter(!is.na(`Temp(C)` )) %>% mutate(delta_T = paste0(round(100*(`Temp(C)` - lag(`Temp(C)`))/lag(`Temp(C)`)),'%')) %>% right_join(t) %>% arrange(Date)
Joining, by = c("Date", "Temp(C)")
# A tibble: 7 x 3
Date `Temp(C)` delta_T
<chr> <dbl> <chr>
1 09-22 14 NA%
2 09-29 19.6 40%
3 10-15 NA NA
4 10-28 11 -44%
5 11-06 NA NA
6 11-21 8 -27%
7 12-13 6 -25%
我有一个 table(如下所列),我们在其中测量了一口井的温度。不幸的是(主要是由于天气)井中的水并不总是可以测量的,所以我们有 NA 的持久性。
Date Temp(C)
09-22 14
09-29 19.6
10-15 NA
10-28 11
11-06 NA
11-21 8
12-13 6
所以我想做的是创建一个新列来计算 Delta T 或温度从一个采样日期到下一个采样日期的变化,等等。如果有 NA,我想避免它并使用最后采样的温度进行计算。但我不知道如何编写该代码。
是这样的吗?
df$TempDiff <- c(NA_real_, diff(zoo::na.locf(df$`Temp(C)`)))
na.locf
表示用最近的 non-NA 替换 NA
。
输出看起来像这样
# A tibble: 7 x 3
Date `Temp(C)` TempDiff
<chr> <dbl> <dbl>
1 09-22 14 NA
2 09-29 19.6 5.6
3 10-15 NA 0
4 10-28 11 -8.6
5 11-06 NA 0
6 11-21 8 -3
7 12-13 6 -2
分组进行
df <- dplyr::group_by(df, Well)
dplyr::mutate(df, TempDiff = c(NA_real_, diff(zoo::na.locf(`Temp(C)`))))
输出
# A tibble: 7 x 4
# Groups: Well [2]
Date `Temp(C)` Well TempDiff
<chr> <dbl> <dbl> <dbl>
1 09-22 14 1 NA
2 09-29 19.6 1 5.6
3 10-15 NA 1 0
4 10-28 11 2 NA
5 11-06 NA 2 0
6 11-21 8 2 -3
7 12-13 6 2 -2
作为 zoo::na.locf
的替代方案,我们可以使用 tidyr 包中的 fill
> library(dplyr)
> library(tidyr)
> df %>%
fill(`Temp(C)`) %>%
mutate(Temp2 = c(NA, diff(`Temp(C)`)))
Date Temp(C) Temp2
1 09-22 14.0 NA
2 09-29 19.6 5.6
3 10-15 19.6 0.0
4 10-28 11.0 -8.6
5 11-06 11.0 0.0
6 11-21 8.0 -3.0
7 12-13 6.0 -2.0
一个data.table
单行
library( data.table )
setDT(mydata)[ !is.na( Temp ), delta := Temp - shift(Temp, type = "lag")]
# Date Temp delta
# 1: 09-22 14.0 NA
# 2: 09-29 19.6 5.6
# 3: 10-15 NA NA
# 4: 10-28 11.0 -8.6
# 5: 11-06 NA NA
# 6: 11-21 8.0 -3.0
# 7: 12-13 6.0 -2.0
如果您需要百分比:
> t %>% filter(!is.na(`Temp(C)` )) %>% mutate(delta_T = paste0(round(100*(`Temp(C)` - lag(`Temp(C)`))/lag(`Temp(C)`)),'%')) %>% right_join(t) %>% arrange(Date)
Joining, by = c("Date", "Temp(C)")
# A tibble: 7 x 3
Date `Temp(C)` delta_T
<chr> <dbl> <chr>
1 09-22 14 NA%
2 09-29 19.6 40%
3 10-15 NA NA
4 10-28 11 -44%
5 11-06 NA NA
6 11-21 8 -27%
7 12-13 6 -25%