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

R 在分组df中的组之间复制数据,r,dplyr,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) <

我对数据进行了分组,其中包含缺失值的块。我使用
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)) 
在这种情况下,我想将第2组中的
var
值替换为第1组中的
var
值,并通过检测第2组中的
total=0
来实现

我试图提出一个自定义函数,将其输入到执行此操作的
do()
,但不知道如何告诉它将当前组中的值替换为其他组中的值。对于上面的示例,我尝试了以下方法,这些方法将始终使用组1中的值进行替换:

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

do(df, CheckDay)

有什么办法可以让它发挥作用吗?

有几件事正在进行。首先,您需要确保
df
是一个
data.frame
,您的函数
CheckDay(x)
既有局部变量
x
,您给它赋值
df
作为全局变量
df
本身,最好将函数中的所有内容都保持为局部变量。最后,您对
do(df,CheckDay(.)
的调用缺少
(.)
部分。试试这个,这个应该可以:

library("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))
df <- as.data.frame(df)


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

result <- do(df, CheckDay(.))
print(result)
库(“dplyr”)

df为了扩展Brouwer的答案,以下是我为实现我的目标而实施的措施:

  • 如前所述生成
    df
  • 创建
    df.shift
    ,一份包含组1、1、2的df副本。。。etc——即变量下移一组的df。(df.shift的
    df.shift
    组1中的行也可以是空的。)
  • 获取
    total=0
    的索引,并将值从
    df复制到这些索引处的
    df

这一切都可以在base R中完成。它创建一个副本,但比在组上循环要便宜得多,速度也快得多

如果需要的话,我愿意使用base或data.table。我认为我需要在CheckDay中有效地使用df作为全局变量(利用它始终存在于CheckDay的父环境中这一事实)。我看那没必要。非常感谢。但我仍然需要弄清楚如何对其进行泛化,以便对于更大的数据帧,它将从前面的组(而不是示例中指定的组)中获取值。也许我可以在一个因子上分组,并使用因子级别作为代理?你应该能够轻松地循环所有的分组号,将它们存储在一个向量中。无论何时,只要所有组总数
0
都抓住组向量中的上一个条目,并相应地设置
var
。循环是我希望避免的,因为我有5788个组。但是,一旦我有了零数据的索引(我可以从df$total==0获得),我就可以用df$var的预移位副本中的值来替换这些索引。
Error: Results are not data frames at positions: 1, 2
library("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))
df <- as.data.frame(df)


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

result <- do(df, CheckDay(.))
print(result)