【问题标题】:Conditional within pipe and summarise not finding column name在管道内有条件并汇总未找到列名
【发布时间】:2020-08-19 05:40:39
【问题描述】:

我在管道中包含条件时遇到问题。在我的代码中,我将一个函数应用于数据,并根据是否有任何积极的结果来总结数据。如果没有阳性结果,我需要输出为“NA”。

library(tidyverse)

df<-tibble(
  lab1=c(rep("cat", 5), rep("carrot", 5), rep("granite", 5)),
  lab2=c(rep("animal", 5), rep("vegetable", 5), rep("mineral", 5)),
  res=c(9.90, 10.90, 11.20, 8.70, 10.10, 9.66, 13.00, 8.88, 9.33, 8.77, 7, 7, 7,  7, 7)
)

TestSameVal<-function(d){
  if (length(unique(d$res))==1){
    return(TRUE)} else return(FALSE)
}

 result<-
  df%>%
  group_by(lab1, lab2)%>%
  nest()%>%
  mutate(all_sameval=map(data, TestSameVal))%>% #Returns TRUE if all measurements for a given variable are the same value
  unnest(all_sameval)%>%
  filter(all_sameval==T)%>% #Filter on only those variables with the same value
  unnest(data)%>%
  select(-all_sameval)%>%
  {if (length(.$res)>0) summarise(rep_val=mean(res)) else T=NA}
#If there are any results where all_sameval is TRUE, summarise the results. Otherwise, assign NA

代码通过 select(-all_sameval) 运行良好。我收到以下由summarise 内容引起的错误:

Error in mean(res) : object 'res' not found

另外,当我运行以下代码时,它工作得很好:

df%>%
  group_by(lab1, lab2)%>%
  nest()%>%
  mutate(all_sameval=map(data, TestSameVal))%>% 
  unnest(all_sameval)%>%
  filter(all_sameval==T)%>% 
  unnest(data)%>%
  select(-all_sameval)%>%
  summarise(rep_val=mean(res))

我意识到我可以使用管道外部的条件来处理这个问题,但如果可能的话,我宁愿保持精简。真正让我崩溃的是,这段代码昨天运行良好。我已经尝试更新我的所有软件包并重新启动 R。

非常感谢任何帮助!

【问题讨论】:

  • 使用{if (length(.$res)&gt;0) {. %&gt;% summarise(rep_val=mean(res))} else NA}。 IF打断了管道,需要再传一遍
  • 接近了!它不太奏效,但{if (length(select(.,lab1)%&gt;%pull())&gt;0) summarise(., rep_val=mean(res)) else T=NA} 确实奏效了。谢谢!

标签: r dplyr


【解决方案1】:

在 OP 的代码中,我们可以将 . 包装在 {}

library(dplyr)
df%>%
   group_by(lab1, lab2)%>%
   nest()%>%
   mutate(all_sameval=map(data, TestSameVal))%>% #Returns TRUE if all measurements for a given variable are the same value
   unnest(all_sameval)%>%
   filter(all_sameval==T)%>% #Filter on only those variables with the same value
   unnest(data)%>%
   select(-all_sameval)%>%
   {if (length(.$res)>0) {.} %>% 
        summarise(rep_val=mean(res)) else T=NA}
# A tibble: 1 x 3
# Groups:   lab1 [1]
#  lab1    lab2    rep_val
#  <chr>   <chr>     <dbl>
#1 granite mineral       7

如果我们返回 map_lgl 作为 filter 中的逻辑向量,我们可以避免创建列 'all_sameval'

library(dplyr)
library(purrr)
df %>%
    group_by(lab1, lab2)%>%
    nest() %>% 
    filter(map_lgl(data, TestSameVal)) %>% 
    unnest(data) %>% 
    summarise(rep_val = mean(res))
# A tibble: 1 x 3
# Groups:   lab1 [1]
#  lab1    lab2    rep_val
#  <chr>   <chr>     <dbl>
#1 granite mineral       7

如果意图是 filter 出组只有一个唯一的 'res' 值并获得 mean

df %>%
     group_by(lab1, lab2) %>%
     filter(n_distinct(res) > 1 & !all(is.na(res))) %>% 
     summarise(res = mean(res, na.rm = TRUE))

【讨论】:

  • 当然,但这并不能解决我的问题——我需要条件语句。在某些情况下,没有重复值,需要分配 NA。
  • @aleoconn 你能显示你的预期输出吗?是否要过滤掉“res”唯一的组?
  • 我已编辑以澄清问题的要点。正如我所说,我可以很好地得到摘要。这是给我带来麻烦的条件。
  • @aleoconn 关于您的代码,它需要一个简单的修复。更新解决方案
猜你喜欢
  • 1970-01-01
  • 2016-09-25
  • 2022-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-11
  • 1970-01-01
  • 2011-10-05
相关资源
最近更新 更多