在dplyr中有条件地改变数据

时间:2016-01-06 21:59:58

标签: r dplyr

我试图通过基于标识符进行划分来改变数据。 例如,我想在以下数据中改变mass。如果它是深度10,我想除以2.如果它是深度20,我想除以3。

day    year    depth    mass 
1      2008    10       13
2      2008    10       15
1      2008    20       14
2      2008    20       12
1      2009    10       14
2      2009    10       16
1      2009    20       12
2      2009    20       18   

分部导致:

day    year    depth    mass 
1      2008    10      6.5
1      2008    10      6.5
2      2008    10      7.5
2      2008    10      7.5
1      2008    20      4.6
1      2008    20      4.6
2      2008    20      4
2      2008    20      4
1      2009    10      7
1      2009    10      7
2      2009    10      8
2      2009    10      8   
1      2009    20      4
1      2009    20      4  
2      2009    20      6 
2      2009    20      6  

我正在尝试以下列方式ifelse,但得到错误“未使用的参数(c(13,15,14 ...)”

df%>% 
  group_by(day, year, depth) %>% 
  bind_rows(., .) %>%
  mutate(mass = ifelse(depth == 10), mass/2,
         ifelse(depth == 20), mass/3)%>%
  arrange(day, year, depth, mass)

3 个答案:

答案 0 :(得分:6)

我在使用ifelse时发现了两个错误。你有ifelse(depth == 10)的地方,你只需要ifelse一个需要三个的参数。删除右括号,你就有了一个良好的开端。

您的第二个错误是,如果第二个ifelse条件解析为FALSE,您没有说明该怎么做。在下面的代码中,我已为此情况指定了NA。我不确定这是否是你想要的行为,所以你应该把它改成适合你需要的行为。

df%>% 
  group_by(day, year, depth) %>% 
  bind_rows(., .) %>%
  mutate(mass = ifelse(test = (depth == 10), 
                       yes = mass/2,
                       no = ifelse(test = (depth == 20), 
                                   yes = mass/3,
                                   no = NA))) %>%
  arrange(day, year, depth, mass)

答案 1 :(得分:4)

用法:

ifelse(test, yes, no)

在你的情况下:

ifelse(depth == 10, mass/2, ifelse(depth == 20, mass/3 , mass))

答案 2 :(得分:0)

Modulo运算符在这里工作得很好。

df %>%
    mutate(mass = mass *
        as.integer(!(depth %% 10)) * 1 / 2 +
        as.integer(!(depth %% 20)) * 1 / 3 
    ) %>%
arrange(day, year, depth, mass)

# let underscore _ denote previous line result
# depth %% 10   ---> remainder left over after modulus division
# !(_)          ---> coerce integer to logical and negate 
# as.integer(_) ---> coerce back to integer for arithmetic operations