汇总数据框并在单个列中进行计算

时间:2019-03-22 15:04:39

标签: r dplyr

我的初始数据框看起来:

library(tidyverse)

df <- tibble::tribble(
        ~element,     ~label, ~value,
            "aa", "sessions",    196,
            "bb", "sessions",    865,
            "aa",    "begin",     59,
            "bb",    "begin",    123,
            "aa", "complete",      5,
            "bb", "complete",      5
        )

我想在一个新的数据框中进行聚合:

  • 每行将包含一个包含比率的列

    1. 开始/会话
    2. 完成/会话

对于每个元素aabb

看起来像:

df_agg <- tibble::tribble(
                          ~label_2,         ~aa,         ~bb,
               "begin_to_sessions", 0.301020408, 0.142196532,
            "complete_to_sessions", 0.005780347, 0.005780347
            )

2 个答案:

答案 0 :(得分:2)

可以先将spread设置为“宽”格式,然后将gather设置为“长”格式,再将spread恢复为“宽”格式。 >

library(tidyverse)
df %>% 
    spread(label, value) %>%
    transmute(element,
              begin_to_sessions = begin/sessions, 
              complete_to_sessions = complete/sessions) %>% 
    gather(label_2, val, -element) %>% 
    spread(element, val)

或使用mutate_at(如果有很多列)

df %>% 
    spread(label, value) %>% 
    mutate_at(vars(begin, complete), list(~ ./sessions)) %>% 
    select(-sessions) %>% 
    rename_at(vars(begin, complete), ~ paste0(., "_to_sessions")) %>% 
    gather(label_2, val, -element) %>% 
    spread(element, val)
# A tibble: 2 x 3
#  label_2                  aa      bb
#  <chr>                 <dbl>   <dbl>
#1 begin_to_sessions    0.301  0.142  
#2 complete_to_sessions 0.0255 0.00578

我们还可以通过执行gather/spread除法来提取多个group_by,以提取与“标签”中“会话”字符串相对应的“值”,filter从具有“会话”的行中在“标签”中,然后在末尾做一个spread

df %>%
  group_by(element) %>% 
  mutate(value = value/value[label ==  "sessions"]) %>% 
  ungroup %>%
  filter(label != "sessions") %>% 
  transmute(element, value, label2 = paste0(label, "_to_sessions")) %>% 
  spread(element, value)

答案 1 :(得分:0)

使用tidyverse,您还可以执行以下操作:

df %>%
 filter(label != "sessions") %>%
 full_join(df %>%
 filter(label == "sessions"), by = c("element" = "element")) %>%
 group_by(element, label.x) %>%
 transmute(label = paste(label.x, "to", label.y, sep = "_"),
           res = value.x/value.y) %>%
 ungroup() %>%
 select(-label.x) %>%
 spread(element, res)

  label                    aa      bb
  <chr>                 <dbl>   <dbl>
1 begin_to_sessions    0.301  0.142  
2 complete_to_sessions 0.0255 0.00578