【问题标题】:dplyr: divide all values in group by group's first valuedplyr:将组中的所有值除以组的第一个值
【发布时间】:2019-01-24 10:33:38
【问题描述】:

我的 df 看起来像这样:

ID    Obs    Value
1     1      26
1     2      13
1     3      52
2     1      1,5
2     2      30

使用 dplyr,我添加了额外的列 Col,这是列值中的所有值除以该列中组的第一个值的结果。

ID    Obs    Value    Col
1     1      26       1
1     2      13       0,5
1     3      52       2
2     1      1,5      1
2     2      30       20

我该怎么做?

【问题讨论】:

标签: r dplyr


【解决方案1】:

按“ID”分组后,使用mutate将“Value”除以“Value”的first创建一个新列

library(dplyr)
df1 %>%
   group_by(ID) %>%
   mutate(Col = Value/first(Value))

如果first 'Value' 为 0 并且我们不想使用它,则使用逻辑表达式对 'Value' 进行子集化,然后取其中的 first

df1 %>%
   group_by(ID) %>%
    mutate(Col = Value/first(Value[Value != 0]))

或在base R

df1$Col <- with(df1, Value/ave(Value, ID, FUN = head, 1))

注意:“值”中的逗号表示它是 character 列。在这种情况下,应该首先将其更改为十进制(.),如果是这种情况,则转换为nunmeric,然后进行除法。可以边读数据边做

【讨论】:

  • 在 dplyr 中有没有办法动态定义值?有些组的第一个值为 0,我想通过除以第一个值来避免 INF!= 0。
  • @TImHaus。在这种情况下,将mutate 更改为mutate(Col = Value/first(Value[Value != 0]))
【解决方案2】:

或者,不创建额外的列:

library(tidyverse)

df = data.frame(ID=c(1,1,1,2,2), Obs=c(1,2,3,1,2), Value=c(26, 13, 52, 1.5, 30))

df %>% 
  group_by(ID) %>% 
  mutate_at('Value', ~./first(.))
#> # A tibble: 5 x 3
#> # Groups:   ID [2]
#>      ID   Obs Value
#>   <dbl> <dbl> <dbl>
#> 1     1     1   1  
#> 2     1     2   0.5
#> 3     1     3   2  
#> 4     2     1   1  
#> 5     2     2  20

### OR ###
df %>% 
  group_by(ID) %>% 
  mutate_at('Value', function(x) x/first(x))
#> # A tibble: 5 x 3
#> # Groups:   ID [2]
#>      ID   Obs Value
#>   <dbl> <dbl> <dbl>
#> 1     1     1   1  
#> 2     1     2   0.5
#> 3     1     3   2  
#> 4     2     1   1  
#> 5     2     2  20

reprex package (v0.3.0) 于 2020-01-04 创建

【讨论】:

    猜你喜欢
    • 2019-08-03
    • 1970-01-01
    • 2022-12-19
    • 1970-01-01
    • 2011-12-02
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多