【问题标题】:Adding na.omit() in mutate with lag and cummax causes "Error: Column must be length x (the group size) or one, not 0"在具有滞后和 cummax 的 mutate 中添加 na.omit() 会导致“错误:列必须是长度 x(组大小)或 1,而不是 0”
【发布时间】:2019-11-13 20:04:44
【问题描述】:

我正在使用 dplyr 来改变我的数据框中的列。它包括创建当前行值与迄今为止的最大值的比率(基本上是滞后和 cummax 组合)。 它工作得很好。除非有 NA 值,因为以下所有计算都变为 NA。

我尝试将 na.omit() 放置在这里和那里,但虽然它可能有效,但该函数失败,因为 na.omit() 与向量的长度混淆并崩溃。

这是我的可重现代码:

v1<-c(NA,100,80,40,NA,30,100,40,20,10,NA,NA,1,NA)
v2<-c(100,100,90,50,NA,-40,NA,-10,NA,NA,NA,1,NA,NA)
group<-c(1,1,1,1,1,1,2,2,2,2,2,3,3,4)

x1<-as.data.frame(cbind(v1,v2,group))


library(dplyr)
for ( i in c("v1","v2")){ 

  x1<-x1 %>% 
    group_by(group) %>%
    mutate( !!sym(paste( i,"_max_lag_ratio", sep="")) :=  get(i)/ lag( as.vector(cummax( get(i)))  , default=first(get(i))))


}

如果我添加 na.omit() 如下:

mutate( !!sym(paste( i,"_max_lag_ratio", sep="")) := get(i)/ lag( cummax( na.omit(get(i)))  , default=first( get(i)  )))

我收到以下错误:

Error: Column `column_max_lag_ratio` must be length 1 (the group size), not 0

很可能是因为一个组(第 4 组)只有 NA。 我怎样才能使这个故障安全?我的真实数据集具有“不完美”的数据。 非常感谢您的帮助,因为我真的被卡住了。

【问题讨论】:

  • 我想出了一个可能的解决方案,但是当我想出它时,nas 的角色并不清楚。对于您的计算, na 不应该在那里,特别是在第一次观察该组时。您应该排除它们以计算要以比率或差异有意义的方式对它们进行编码的变量。

标签: r dplyr


【解决方案1】:

基于此答案Need to get R cummax but dealing properly with NAs 的可行解决方案可能是:

 df %>% 
    replace_na(list(v1=-Inf, v2=-Inf)) %>% 
    group_by(group) %>% 
    mutate(max_v1 = cummax(v1), 
                 max_v2 = cummax(v2)
                 ) %>% 
    group_by(group) %>% 
    mutate(v1_max_lag_ratio = v1/lag(max_v1)) %>% 
    mutate(v2_max_lag_ratio = v2/lag(max_v2))

【讨论】:

  • 找到了解决方法并已发布。谢谢。顺便说一句,这会返回could not find function "replace_na"
【解决方案2】:

做了这个解决方法并成功了。

v1<-c(NA,100,80,40,NA,30,100,40,20,10,NA,NA,1,NA)
v2<-c(100,100,90,50,NA,-40,NA,-10,NA,NA,NA,1,NA,NA)
group<-c(1,1,1,1,1,1,2,2,2,2,2,3,3,4)

x1<-as.data.frame(cbind(v1,v2,group))


library(dplyr)
for ( i in c("v1","v2")){ 

  x1<-x1 %>% 
    group_by(group) %>%
    mutate( !!sym(paste( i,"_max_lag_ratio", sep="")) :=  get(i)/(lag( cummax( ifelse(is.na(get(i)), na.omit(get(i) ) ,get(i)))  , default=first(get(i))))
    )  

}

【讨论】:

    猜你喜欢
    • 2020-06-14
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 2015-08-25
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    • 1970-01-01
    相关资源
    最近更新 更多