groupby之后在多列中应用不同的功能

时间:2018-08-01 07:43:31

标签: r dataframe dplyr aggregate

在groupby之后,我正在努力将head(1)应用于列,将聚合应用于另一列,并将逻辑表达式应用于另一列。

我有一个像这样的数据框df

df <- data.frame(ref = c(rep("123", 3), rep("456", 3), rep("789", 4)),
                 carrier = c("A", "A", "B", "C", "C", "C", "D", "E", "F", "A"), 
                 distance = c(20, 10, 40, 20, 90, 30, 20, 20, 30, 70),
                 stringsAsFactors = FALSE)


>df
ref    carrier    distance
123          A          20
123          A          10
123          B          40
456          C          20
456          C          90
456          C          30
789          D          20
789          E          20
789          F          30
789          A          70

我想在下面做这些事情。

  1. ref分组

  2. 对列first_carrier进行突变,在该列中返回每个组的carrier列的第一个值

  3. 对列agg_distance进行突变,以返回每个组中distance列的汇总值

  4. 对列plus_100进行突变,如果agg_distance大于350,而FALSE小于100,则返回TRUE。

所以结果应该像这样。

ref  first_carrier  agg_distance  plus_100
123              A            70     FALSE
456              C           140      TRUE  
789              D           140      TRUE

我的尝试

  df_new <- df %>%
    group_by(ref) %>%
    mutate("agg_distance" = summarise(sum(distance)) %>%
    mutate("plus_100" = ifelse(agg_distance >= 100, T, F))

但是我不确定如何在每个组中选择第一个承运人。

2 个答案:

答案 0 :(得分:2)

您几乎自己拥有了它。 summarisemutate一起使用。要获得第一个运营商,只需在分组后调用carrier列的第一行即可。

library(dplyr)

df_new <- df %>%
  group_by(ref) %>%
  summarise(first_carrier = carrier[1],
            agg_distance = sum(distance),
            plus_100 = ifelse(agg_distance >= 100, T, F))

# A tibble: 3 x 4
    ref first_carrier agg_distance plus_100
  <chr>         <chr>        <dbl>    <lgl>
1   123             A           70    FALSE
2   456             C          140     TRUE
3   789             D          140     TRUE

答案 1 :(得分:1)

这是由@LAP输入制成的data.table版本:

请向LAP赞一下

df<-
setDT(df)[,.(first_carrier = carrier[1],
             agg_distance  = sum(distance)),by="ref"][,plus_100 := ifelse(agg_distance >= 100, T, F)]

#> df
#   ref first_carrier agg_distance plus_100
#1: 123             A           70    FALSE
#2: 456             C          140     TRUE
#3: 789             D          140     TRUE