使用dplyr进行group_by并仅使用if(不包含else)语句进行条件突变

时间:2019-01-28 14:25:58

标签: r dplyr mutate

我有一个数据框,我需要按列条目进行分组,以便仅使用if语句(不包含else条件)有条件地对几列进行变异。

更具体地说,如果某个组的列值超过预定义的阈值,我想对其求和,否则这些值应保持不变。

我尝试同时使用if_elsecase_when来执行此操作,但是这些函数需要“ false”参数(if_else)或默认情况下设置与NA不匹配的值( case_when):

iris_mutated <- iris %>%
  dplyr::group_by(Species) %>%
  dplyr::mutate(Sepal.Length=if_else(sum(Sepal.Length)>250, sum(Sepal.Length)),
                Sepal.Width=if_else(sum(Sepal.Width)>170, sum(Sepal.Width)),
                Petal.Length=if_else(sum(Petal.Length)>70, sum(Petal.Length)),
                Petal.Width=if_else(sum(Petal.Width)>15, sum(Petal.Width)))

iris_mutated <- iris %>%
  dplyr::group_by(Species) %>%
  dplyr::mutate(Sepal.Length=case_when(sum(Sepal.Length)>250 ~ sum(Sepal.Length)),
                Sepal.Width=case_when(sum(Sepal.Width)>170 ~ sum(Sepal.Width)),
                Petal.Length=case_when(sum(Petal.Length)>70 ~ sum(Petal.Length)),
                Petal.Width=case_when(sum(Petal.Width)>15 ~ sum(Petal.Width)))

有什么主意怎么做?

编辑:

以下是预期输出的示例。 对于所有按物种分组的条目,花瓣宽度的总和对于 setosa 为12.3,对于 virginica 为101.3,对于 versicolor 为66.3。如果我要求此总和至少应为15以求和(否则应保留原始值),那么我期望得到以下输出(仅显示“ Petal.Width”和“ Species”列):

Petal.Width    Species
1           0.2     setosa
2           0.2     setosa
3           0.2     setosa
4           0.2     setosa
5           0.2     setosa
6           0.4     setosa
7           0.3     setosa
8           0.2     setosa
9           0.2     setosa
10          0.1     setosa
#...#
50          0.2     setosa
51          66.3 versicolor
52          66.3 versicolor
53          66.3 versicolor
#...#
100         66.3 versicolor
101         101.3  virginica
102         101.3  virginica
103         101.3  virginica
#...#
150         101.3  virginica

1 个答案:

答案 0 :(得分:2)

我想你是在追捕吗?使用约翰尼的方法。如果将原始值用作case_w的一部分,且总和不大于临界值,则不会出错。

iris_mutated <- iris %>% 
  group_by(Species) %>% 
  mutate(Sepal.Length = case_when(sum(Sepal.Length) > 250 ~ sum(Sepal.Length),
                                   T ~ Sepal.Length),
         Sepal.Width = case_when(sum(Sepal.Width) > 170 ~ sum(Sepal.Width),
                                   T ~ Sepal.Width),
         Petal.Length = case_when(sum(Petal.Length) > 70 ~ sum(Petal.Length),
                                   T ~ Petal.Length),
         Petal.Width = case_when(sum(Petal.Width) > 15 ~ sum(Petal.Width),
                                   T ~ Petal.Width))