R:按组对 NA 进行插值
R: Interpolation of NAs by group
我想在数据帧的变量中执行线性插值,其中考虑了:1) 两点之间的时间差,2) 获取数据的时间和 3) 获取的个人用于测量变量。
例如在下一个数据帧中:
df <- data.frame(time=c(1,2,3,4,5,6,7,1,2,3),
Individuals=c(1,1,1,1,1,1,1,2,2,2),
Value=c(1, 2, 3, NA, 5, NA, 7, 5, NA, 7))
df
我想获得:
result <- data.frame(time=c(1,2,3,4,5,6,7,1,2,3),
Individuals=c(1,1,1,1,1,1,1,2,2,2),
Value=c(1, 2, 3, 4, 5, 6, 7, 5, 5.5, 6))
result
我不能单独使用包 zoo
的功能 na.approx
因为所有的观察都不是连续的,一些观察属于一个人而其他观察属于其他人。原因是因为如果第二个人第一次观察 NA
而我将专门使用函数 na.approx
,我将使用来自 individual==1
的信息来插入 [=16] =] 的 individual==2
(例如,下一个数据帧会有这样的错误)
df_2 <- data.frame(time=c(1,2,3,4,5,6,7,1,2,3),
Individuals=c(1,1,1,1,1,1,1,2,2,2),
Value=c(1, 2, 3, NA, 5, NA, 7, NA, 5, 7))
df_2
我试过使用软件包 zoo
和 dplyr
:
library(dplyr)
library(zoo)
proof <- df %>%
group_by(Individuals) %>%
na.approx(df$Value)
但我无法在 zoo
对象中执行 group_by
。
你知道如何在一个变量中按组插入 NA
值吗?
提前致谢,
使用 data.frame
,而不是 cbind
来创建您的数据。 cbind
returns 一个矩阵,但是 dplyr
需要一个数据框。然后在mutate
里面使用na.approx
。我已经注释掉了 group_by
,因为您没有在数据中提供分组变量,但是一旦您将分组变量添加到数据框,该方法就应该起作用。
df <- data.frame(time=c(1,2,3,4,5,6,7,1,2,3),
Individuals=c(1,1,1,1,1,1,1,2,2,2),
Value=c(NA, 2, 3, NA, 5, NA, 7, 8, NA, 10))
library(dplyr)
library(zoo)
df %>%
group_by(Individuals) %>%
mutate(ValueInterp = na.approx(Value, na.rm=FALSE))
time Individuals Value ValueInterp
1 1 1 NA NA
2 2 1 2 2
3 3 1 3 3
4 4 1 NA 4
5 5 1 5 5
6 6 1 NA 6
7 7 1 7 7
8 1 2 8 8
9 2 2 NA 9
10 3 2 10 10
更新:要插入多列,我们可以使用mutate_at
。下面是一个包含两个值列的示例。我们在列名称中包含 "Value"
的所有列上使用 mutate_at
到 运行 na.approx
。 list(interp=na.approx)
告诉 mutate_at
通过 运行 宁 na.approx
并添加 interp
作为后缀来生成新的列名:
df <- data.frame(time=c(1,2,3,4,5,6,7,1,2,3),
Individuals=c(1,1,1,1,1,1,1,2,2,2),
Value1=c(NA, 2, 3, NA, 5, NA, 7, 8, NA, 10),
Value2=c(NA, 2, 3, NA, 5, NA, 7, 8, NA, 10)*2)
df %>%
group_by(Individuals) %>%
mutate_at(vars(matches("Value")), list(interp=na.approx), na.rm=FALSE)
time Individuals Value1 Value2 Value1_interp Value2_interp
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 1 NA NA NA NA
2 2 1 2 4 2 4
3 3 1 3 6 3 6
4 4 1 NA NA 4 8
5 5 1 5 10 5 10
6 6 1 NA NA 6 12
7 7 1 7 14 7 14
8 1 2 8 16 8 16
9 2 2 NA NA 9 18
10 3 2 10 20 10 20
如果您不想保留原始的、未插值的列,您可以这样做:
df %>%
group_by(Individuals) %>%
mutate_at(vars(matches("Value")), na.approx, na.rm=FALSE)
我们可以使用data.table
library(data.table)
library(zoo)
setDT(df1)[, ValueInterp:= na.approx(Value, na.rm=TRUE), by = Individual]
我想在数据帧的变量中执行线性插值,其中考虑了:1) 两点之间的时间差,2) 获取数据的时间和 3) 获取的个人用于测量变量。
例如在下一个数据帧中:
df <- data.frame(time=c(1,2,3,4,5,6,7,1,2,3),
Individuals=c(1,1,1,1,1,1,1,2,2,2),
Value=c(1, 2, 3, NA, 5, NA, 7, 5, NA, 7))
df
我想获得:
result <- data.frame(time=c(1,2,3,4,5,6,7,1,2,3),
Individuals=c(1,1,1,1,1,1,1,2,2,2),
Value=c(1, 2, 3, 4, 5, 6, 7, 5, 5.5, 6))
result
我不能单独使用包 zoo
的功能 na.approx
因为所有的观察都不是连续的,一些观察属于一个人而其他观察属于其他人。原因是因为如果第二个人第一次观察 NA
而我将专门使用函数 na.approx
,我将使用来自 individual==1
的信息来插入 [=16] =] 的 individual==2
(例如,下一个数据帧会有这样的错误)
df_2 <- data.frame(time=c(1,2,3,4,5,6,7,1,2,3),
Individuals=c(1,1,1,1,1,1,1,2,2,2),
Value=c(1, 2, 3, NA, 5, NA, 7, NA, 5, 7))
df_2
我试过使用软件包 zoo
和 dplyr
:
library(dplyr)
library(zoo)
proof <- df %>%
group_by(Individuals) %>%
na.approx(df$Value)
但我无法在 zoo
对象中执行 group_by
。
你知道如何在一个变量中按组插入 NA
值吗?
提前致谢,
使用 data.frame
,而不是 cbind
来创建您的数据。 cbind
returns 一个矩阵,但是 dplyr
需要一个数据框。然后在mutate
里面使用na.approx
。我已经注释掉了 group_by
,因为您没有在数据中提供分组变量,但是一旦您将分组变量添加到数据框,该方法就应该起作用。
df <- data.frame(time=c(1,2,3,4,5,6,7,1,2,3),
Individuals=c(1,1,1,1,1,1,1,2,2,2),
Value=c(NA, 2, 3, NA, 5, NA, 7, 8, NA, 10))
library(dplyr)
library(zoo)
df %>%
group_by(Individuals) %>%
mutate(ValueInterp = na.approx(Value, na.rm=FALSE))
time Individuals Value ValueInterp 1 1 1 NA NA 2 2 1 2 2 3 3 1 3 3 4 4 1 NA 4 5 5 1 5 5 6 6 1 NA 6 7 7 1 7 7 8 1 2 8 8 9 2 2 NA 9 10 3 2 10 10
更新:要插入多列,我们可以使用mutate_at
。下面是一个包含两个值列的示例。我们在列名称中包含 "Value"
的所有列上使用 mutate_at
到 运行 na.approx
。 list(interp=na.approx)
告诉 mutate_at
通过 运行 宁 na.approx
并添加 interp
作为后缀来生成新的列名:
df <- data.frame(time=c(1,2,3,4,5,6,7,1,2,3),
Individuals=c(1,1,1,1,1,1,1,2,2,2),
Value1=c(NA, 2, 3, NA, 5, NA, 7, 8, NA, 10),
Value2=c(NA, 2, 3, NA, 5, NA, 7, 8, NA, 10)*2)
df %>%
group_by(Individuals) %>%
mutate_at(vars(matches("Value")), list(interp=na.approx), na.rm=FALSE)
time Individuals Value1 Value2 Value1_interp Value2_interp <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 1 1 NA NA NA NA 2 2 1 2 4 2 4 3 3 1 3 6 3 6 4 4 1 NA NA 4 8 5 5 1 5 10 5 10 6 6 1 NA NA 6 12 7 7 1 7 14 7 14 8 1 2 8 16 8 16 9 2 2 NA NA 9 18 10 3 2 10 20 10 20
如果您不想保留原始的、未插值的列,您可以这样做:
df %>%
group_by(Individuals) %>%
mutate_at(vars(matches("Value")), na.approx, na.rm=FALSE)
我们可以使用data.table
library(data.table)
library(zoo)
setDT(df1)[, ValueInterp:= na.approx(Value, na.rm=TRUE), by = Individual]