dplyr mutate case的时候

问题描述 投票:0回答:4

我有以下数据:

library(reshape2)
library(dplyr)

d <- tibble(
  Region = c("R1", "R2", "R3", "R4", "R5", "R1","R2","R3", "R4", "R5"),
  Area = c("R123","R234", "R345", "R456", "R567", "R123","R234", "R345", 
"R456", "R567"),
  var1= c(22, 34, 34, 23, 23, 45, 56, 45, 56, 45),
  var2= c(76, 34, 56, 76,23, 34, 23, 43, 23, 44))

我想使用mutate创建一个新列,它是var1和var 2除以2的总和。

这是我必须尝试并执行此操作的代码,但它并不是我想要的。

d %>% 
  mutate (Total = case_when (Region == "R1" & Area == "R123" ~
                              sum(var1 & var2)/2),
      case_when (Region == "R2" & Area == "R234" ~
                              sum(var1 & var2)/2)) -> data

我只想要一个总列,第一行的总值应该是49,所以我不确定5来自哪里。

谢谢

r dplyr
4个回答
2
投票

假设您只想将算法应用于所有行...

如果要保留所有列:

d %>% 
  mutate(Total=(var1+var2)/2) -> new_d

如果你只想保留新的Total专栏:

d %>% 
  transmute(Total=(var1+var2)/2) -> new_d

换句话说,如果你想保持用作例子的条件并将总和应用于某些区域......

default = 0       # define the default value for other cases

d %>% 
  mutate(Total=ifelse(Region=="R1" | Region=="R2", (var1+var2)/2, default)) -> new_d

要么:

default = 0       # define the default value for other cases

d %>% 
  transmute(Total=ifelse(Region=="R1" | Region=="R2", (var1+var2)/2, default)) -> new_d

3
投票

您可以在case_when中一起检查条件,否则返回条件不匹配的0。

library(dplyr)

d %>% 
  mutate(Total = case_when((Region == "R1" & Area == "R123") |
                            (Region == "R2" & Area == "R234") ~ (var1 + var2) / 2, 
                            TRUE ~ 0))  

# A tibble: 10 x 5
#  Region Area   var1  var2 Total
#   <chr>  <chr> <dbl> <dbl> <dbl>
# 1 R1     R123     22    76  49  
# 2 R2     R234     34    34  34  
# 3 R3     R345     34    56   0  
# 4 R4     R456     23    76   0  
# 5 R5     R567     23    23   0  
# 6 R1     R123     45    34  39.5
# 7 R2     R234     56    23  39.5
# 8 R3     R345     45    43   0  
# 9 R4     R456     56    23   0  
#10 R5     R567     45    44   0  

在这种情况下,使用ifelse可以实现同样的目的

d %>% 
  mutate(Total = ifelse((Region == "R1" & Area == "R123") | 
         (Region == "R2" & Area == "R234"), (var1 + var2) / 2,  0))  

1
投票

不使用任何ifelse/case_when,我们可以直接将逻辑向量与'var1','var2'的rowMeans相乘

library(tidyverse)
d %>%
    mutate(Total = (str_c(Region, Area) %in% c("R1R123", "R2R234")) * 
             (var1 + var2)/2)
# A tibble: 10 x 5
#   Region Area   var1  var2 Total
#   <chr>  <chr> <dbl> <dbl> <dbl>
# 1 R1     R123     22    76  49  
# 2 R2     R234     34    34  34  
# 3 R3     R345     34    56   0  
# 4 R4     R456     23    76   0  
# 5 R5     R567     23    23   0  
# 6 R1     R123     45    34  39.5
# 7 R2     R234     56    23  39.5
# 8 R3     R345     45    43   0  
# 9 R4     R456     56    23   0  
#10 R5     R567     45    44   0  

或者在base R

d$Total <- rowMeans(d[3:4]) * (do.call(paste0, d[1:2]) %in% c("R1R123", "R2R234"))
d$Total
#[1] 49.0 34.0  0.0  0.0  0.0 39.5 39.5  0.0  0.0  0.0

0
投票

其他人已经回答了如何做你想做的事情的问题,但回答了5来自哪里的问题:总和是列总和,而不是行和,当你使用&符号组合变量时你得到TRUEFALSE(在这种情况下TRUE)的值。当计算列的总和时,它是10,因为TRUE的数值为1.然后将10除以2得到5。

© www.soinside.com 2019 - 2024. All rights reserved.