【问题标题】:Iterative dividing by specific row for grouped dplyr data in RR中分组dplyr数据的迭代除以特定行
【发布时间】:2020-02-06 23:24:09
【问题描述】:

我想迭代地将每个值除以分组变量的每个级别中的特定行。以下是一些示例数据:

library(tidyverse)

d <- structure(list(group = c("blue", "blue", "blue", "red", "red", 
                     "red", "yellow", "yellow", "yellow", "green", "green", "green"
), level = c("a", "b", "c", "a", "b", "c", "a", "b", "c", "a", 
         "b", "c"), value = c(1.666667, 1.333333, 1, 5, 4, 1, 6, 5, 1, 2.75, 2.25, 1)), row.names = c(NA, 
                                                                                    -12L), class = c("tbl_df", "tbl", "data.frame"))


d
 # A tibble: 12 x 3
   group  level value
   <chr>  <chr> <dbl>
 1 blue   a         5
 2 blue   b         4
 3 blue   c         3
 4 red    a        10
 5 red    b         8
 6 red    c         2
 7 yellow a         6
 8 yellow b         5
 9 yellow c         1
10 green  a        11
11 green  b         9
12 green  c         4

所以,假设我想将在每个组中找到的每个值除以 c 级别。在这种情况下,结果将如下所示:

result
# A tibble: 12 x 3
   group  level value
   <chr>  <chr> <dbl>
 1 blue   a      1.67
 2 blue   b      1.33
 3 blue   c      1   
 4 red    a      5   
 5 red    b      4   
 6 red    c      1   
 7 yellow a      6   
 8 yellow b      5   
 9 yellow c      1   
10 green  a      2.75
11 green  b      2.25
12 green  c      1 

有没有办法使用 tidyverse 功能做到这一点?

【问题讨论】:

    标签: r dplyr tidyverse tibble


    【解决方案1】:

    假设level在'group'中没有重复,按'group'分组后,提取'c'级别(value[level == 'c'])对应的'value'并用它来划分'value ' 列

    library(dplyr)
    d %>% 
       group_by(group) %>%
       mutate(value = value/value[level == 'c'])
    # A tibble: 12 x 3
    # Groups:   group [4]
    #   group  level value
    #   <chr>  <chr> <dbl>
    # 1 blue   a      1.67
    # 2 blue   b      1.33
    # 3 blue   c      1   
    # 4 red    a      5   
    # 5 red    b      4   
    # 6 red    c      1   
    # 7 yellow a      6   
    # 8 yellow b      5   
    # 9 yellow c      1   
    #10 green  a      2.75
    #11 green  b      2.25
    #12 green  c      1   
    

    或者如果有多个'c',则使用match获取'c'第一次出现的索引

    d %>%
      group_by(group) %>%
      mutate(value = value/value[match('c', level)])
    

    或者使用base R

    d$value <-  d$value/with(subset(d, level == 'c'), setNames(value, group)[d$group])
    

    数据

    d <- structure(list(group = c("blue", "blue", "blue", "red", "red", 
    "red", "yellow", "yellow", "yellow", "green", "green", "green"
    ), level = c("a", "b", "c", "a", "b", "c", "a", "b", "c", "a", 
    "b", "c"), value = c(5, 4, 3, 10, 8, 2, 6, 5, 1, 11, 9, 4)), row.names = c(NA, 
    -12L), class = c("tbl_df", "tbl", "data.frame"))
    

    【讨论】:

    • 这非常有效。我没有意识到您可以在列的索引中指定另一列的级别。延迟结束后我会接受。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    相关资源
    最近更新 更多