在分组df中的组之间复制数据

时间:2014-06-19 22:37:31

标签: r dplyr

我对包含缺失值块的数据进行了分组。我使用dplyr来计算每个组的目标变量之和。对于总和为零的组,我想用前一组中的值替换该组的值。我可以在循环中执行此操作,但由于我的数据位于大型数据框中,因此效率极低。

这是一个合成的例子:

df <- tbl_df(as.data.frame(cbind(c(rep(1, 4), rep(2, 4)), 
                           c(abs(rnorm(4)), rep(NA, 4)))))

names(df) <- c("group", "var")

df <- df %>%
        group_by(group) %>%
        mutate(total = sum(var, na.rm = TRUE)) 

输出:

Source: local data frame [8 x 3]
Groups: group

  group       var   total
1     1 1.3697267 4.74936
2     1 1.5263502 4.74936
3     1 0.4065596 4.74936
4     1 1.4467237 4.74936
5     2        NA 0.00000
6     2        NA 0.00000
7     2        NA 0.00000
8     2        NA 0.00000

在这种情况下,我想将第2组中var的值替换为第1组中var的值,我想通过检测total = 0 in来实现第2组。

我尝试提供一个自定义函数来提供do()这样做,但无法弄清楚如何告诉它用当前组中的值替换当前组中的值一个不同的群体。通过上面的示例,我尝试了以下操作,它将始终使用第1组中的值替换:

CheckDay <- function(x) { 
  if( all(x$total == 0) ) { x$var <- df[df$group==1, 2] } ; x 
}

do(df, CheckDay)

CheckDay会返回df,但do()会抛出错误:

Error: Results are not data frames at positions: 1, 2

有没有办法让它发挥作用?

2 个答案:

答案 0 :(得分:1)

有几件事正在发生。首先,您需要确保dfdata.frame,您的函数CheckDay(x)包含局部变量x,您将值df作为全局变量{ {1}}本身,最好将函数保留在本地函数内部。最后,您对df的调用缺少do(df, CheckDay(.))部分。试试这个,这应该有效:

(.)

答案 1 :(得分:0)

为了扩展Brouwer的答案,我实现了以下目标:

  • 如前所述生成df
  • 创建df.shift,df的副本,包含组1,1,2 ......等等 - 即变量向下移动一个组的df。 (df.shift的第1组中的行也可能只是空白。)
  • 获取total = 0的索引,并将df.shift的值复制到df这些索引。

这可以在基础R中完成。它创建一个副本,但比循环组更便宜,更快。