【问题标题】:Streamline dplyr mutation of selected groups简化选定组的 dplyr 突变
【发布时间】:2016-07-09 17:24:16
【问题描述】:

一般性问题:

有没有办法使用 dplyr 来识别感兴趣的组并仅改变这些组?

上述问题的实例化

假设我有一些值,它们被标记为组的一部分。

在某些群体中,价值观的传播范围太大。

我想对这些组的较低值进行调整。

我可以像这样生成一些合成数据:

groups <- floor(runif(1000,1,100))
values <- rnorm(1000,0,1)
df     <- data.frame(group=groups,val=values)

我可以像这样识别感兴趣的群体:

groups_to_adjust <- df %>% group_by(group) %>% summarise(diff=max(val)-min(val)) %>% filter(diff>4) %>% select(group)

然后我可以像这样调整这些组:

df <- df %>% mutate(val=ifelse(group %in% groups_to_adjust$group, ifelse(val<0,val+4,val), val))

理想情况下,所有这些都可以在单个 dplyr 链中完成。有没有一种干净的方法来实现这一目标?我想:

df %>% group_by(group) %>% group_filter(max(val)-min(val)>4) %>% mutate(val=ifelse(val<0,val+4,val)) %>% ungroupfilter()

或类似的东西。

【问题讨论】:

  • ifelsecase_whenfilter %&gt;% mutate %&gt;% left_join 似乎是选项。

标签: r dplyr


【解决方案1】:

没有测试代码,但我认为这是你想要的:

df %>% group_by(group) %>% 
       mutate(val = ifelse(max(val) - min(val) > 4 & val < 0, val + 4, val))

一个小数据框的测试用例:

df
   group   val
1      1  0.00
2      1 -1.56
3      1  0.70
4      1  0.30
5      2 -1.66
6      2 -0.49
7      2 -0.36
8      2  1.67
9      3  0.94
10     3  1.62
11     3  0.89
12     3 -0.53

df %>% group_by(group) %>% 
       mutate(val = ifelse(max(val) - min(val) > 3 & val < 0, val + 4, val))

Source: local data frame [12 x 2]
Groups: group [3]

   group   val
   (int) (dbl)
1      1  0.00
2      1 -1.56
3      1  0.70
4      1  0.30
5      2  2.34
6      2  3.51
7      2  3.64
8      2  1.67
9      3  0.94
10     3  1.62
11     3  0.89
12     3 -0.53

仅替换第二组中的负值,因为其他两组差异小于3

【讨论】:

  • 我怀疑确实如此,尽管这种特殊形式似乎会导致大量的重新计算,并且不会在语法上将组过滤与突变分开。或许没有什么好办法。
  • 我认为你在这个意义上是正确的。使用组过滤器,它可以避免对非预期组进行大量不必要的计算。
  • df %&gt;% group_by(group) %&gt;% mutate(val = ifelse(max(val) - min(val) &gt; 3 , ifelse(val &lt; 0, val + 4, val), val)。我认为您可以尝试一下将 group 和 val 的比较分开。
猜你喜欢
  • 2018-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
  • 2019-05-17
  • 1970-01-01
相关资源
最近更新 更多