我对包含缺失值块的数据进行了分组。我使用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
有没有办法让它发挥作用?
答案 0 :(得分:1)
有几件事正在发生。首先,您需要确保df
是data.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中完成。它创建一个副本,但比循环组更便宜,更快。