1

我想使用zoo::na.approx(但未与此函数结合)为我的数据框中的缺失天数填写响应变量。我很难弄清楚如何将 NA 添加到原始数据框中,以便 na.approx 可以填充它们。

我的数据框看起来像这样:

 df<-data.frame(trt=c("A", "A", "A", "A", "B", "B", "B", "B"),
                day = c(1,3,7,9,1,5,8,9),
                value = c(7,12,5,7,5,6,11,8),
                stringsAsFactors=FALSE)

对于我没有数据的每一天,我希望每一天都在带有“NA”的数据框中。

我用这样的东西来扩展我的数据集:

library(dplyr)

days_possible <- expand.grid(
  day = seq(from=min(df$day), max(df$day), by=1),
  trt = c("A", "B"), 
  stringsAsFactors = FALSE
   )

new_df<- df %>%
   right_join(days_possible, by = c("trt", "day"))

我的问题是我有一堆网站、年份和一些处理列,所以在某个地方似乎都搞砸了,在我的days_possible数据框中,我做错了。

有没有一种功能可以避免这种混乱,展开一列,并让所有其他列以整齐的方式展开?我正在查看modelr::data_grid,但我本身并不确定如何获得最终所需的结果 - 我可以按治疗分组并使用近似值来填补缺失天数的有序数据框。

4

2 回答 2

2

我们可以使用包中的completeandfull_seq函数tidyras.data.frame()不需要决赛。我刚刚添加它以将输出打印为数据框。

library(tidyr)

df2 <- df %>% 
  complete(trt, day = full_seq(day, period = 1)) %>%
  as.data.frame()

df2
#    trt day value
# 1    A   1     7
# 2    A   2    NA
# 3    A   3    12
# 4    A   4    NA
# 5    A   5    NA
# 6    A   6    NA
# 7    A   7     5
# 8    A   8    NA
# 9    A   9     7
# 10   B   1     5
# 11   B   2    NA
# 12   B   3    NA
# 13   B   4    NA
# 14   B   5     6
# 15   B   6    NA
# 16   B   7    NA
# 17   B   8    11
# 18   B   9     8
于 2018-01-05T19:17:16.817 回答
0

我们在最后的注释中添加了一个value2列,df以表明这适用于其他列。

请注意,这df不是时间序列,na.approx旨在对时间序列进行操作。要将其转换为一个,将其读入 zoo 对象wide0,然后将其与一组完整的天数合并。现在我们可以na.approx像讨论的那样直接申请。

library(magrittr)
library(zoo)

wide <- df %>% 
   read.zoo(index = "day", split = "trt") %>%
   merge(zoo(, start(.):end(.) + 0)) %>%
   na.approx

给予:

> wide
  value.A value2.A   value.B value2.B
1    7.00     1.00  5.000000 5.000000
2    9.50     1.50  5.250000 5.250000
3   12.00     2.00  5.500000 5.500000
4   10.25     2.25  5.750000 5.750000
5    8.50     2.50  6.000000 6.000000
6    6.75     2.75  7.666667 6.333333
7    5.00     3.00  9.333333 6.666667
8    6.00       NA 11.000000 7.000000
9    7.00       NA  8.000000 8.000000 

上面的 NA 是由于在两边都没有值的情况下无法进行插值;但是,na.approx如果您愿意,确实有其他参数可以填写。

上面显示的每个变量/组具有单独列的宽格式可能是最方便的,但如果不是,我们可以使用将其转换回长格式,fortify.zoo并可能再次将变量分散到一列中。

library(tidyr)

wide %>%
     fortify.zoo(wide, melt = TRUE, sep = ".", 
         names = list("day", c("variable", "group"), "value")) %>%
     spread(variable, value)

给予:

   day group     value   value2
1    1     A  7.000000 1.000000
2    1     B  5.000000 5.000000
3    2     A  9.500000 1.500000
4    2     B  5.250000 5.250000
5    3     A 12.000000 2.000000
6    3     B  5.500000 5.500000
7    4     A 10.250000 2.250000
8    4     B  5.750000 5.750000
9    5     A  8.500000 2.500000
10   5     B  6.000000 6.000000
11   6     A  6.750000 2.750000
12   6     B  7.666667 6.333333
13   7     A  5.000000 3.000000
14   7     B  9.333333 6.666667
15   8     A  6.000000       NA
16   8     B 11.000000 7.000000
17   9     A  7.000000       NA
18   9     B  8.000000 8.000000

笔记

可重现形式的输入。我们添加了一value2列以显示它仍然有效。

df<-data.frame(trt=c("A", "A", "A", "A", "B", "B", "B", "B"),
                day = c(1,3,7,9,1,5,8,9),
                value = c(7,12,5,7,5,6,11,8),
                stringsAsFactors=FALSE)
df$value2 <- c(1:3, NA, 5:8)
于 2018-01-05T19:29:55.263 回答