在一个tibble中展开一列,然后按照描述性列进行操作

时间:2018-01-05 19:09:11

标签: r dataframe zoo tibble modelr

我想使用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,但我自己并不确定如何获得最终的预期结果 - 一个有序的数据框我可以通过处理分组并使用近似来填补缺失的天数。

2 个答案:

答案 0 :(得分:2)

我们可以使用complete包中的full_seqtidyr函数。最终as.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

答案 1 :(得分:0)

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

请注意,df不是时间序列,na.approx旨在按时间序列运行。要将其转换为一个,请将其读入动物园对象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)