通过多个组计算跨多列的最大值

时间:2018-07-13 19:43:19

标签: r dplyr data.table

我有一个数据文件,该文件在三列中有数值,并且有两个分组变量(ID和Group),我需要根据ID和Group计算一个最大值:

toConcurrentMap

我想要获得的结果是:

structure(list(ID = structure(c(1L, 1L, 1L, 2L), .Label = c("a1", 
"a2"), class = "factor"), Group = structure(c(1L, 1L, 2L, 2L), .Label = 
c("abc", 
"def"), class = "factor"), Score1 = c(10L, 0L, 0L, 5L), Score2 = c(0L, 
0L, 5L, 10L), Score3 = c(0L, 11L, 2L, 11L)), class = "data.frame", row.names = 
c(NA, 
-4L))

我正在dplyr中尝试以下操作:

structure(list(ID = structure(c(1L, 1L, 2L), .Label = c("a1", 
"a2"), class = "factor"), Group = structure(c(1L, 2L, 2L), .Label = c("abc", 
"def"), class = "factor"), Max = c(11L, 5L, 11L)), class = "data.frame", 
row.names = c(NA, 
-3L))

但是它会产生此错误:

SampTable<-SampDF %>% group_by(ID,Group) %>% 
summarize(max = pmax(SampDF$Score1, SampDF$Score2,SampDF$Score3))

Error in summarise_impl(.data, dots) : Column `max` must be length 1 (a summary value), not 4 dplyr中是否有一种简单的方法来实现这一目标?

5 个答案:

答案 0 :(得分:3)

使用# sample array In [120]: some_arr = np.array([1, 1, 1, 1, 1, 1, 1, 1]) # addition after type coercion In [122]: some_arr + (arr1 < scalar) Out[122]: array([2, 2, 2, 2, 2, 2, 1, 1]) # same output achieved with `numpy.less()` In [123]: some_arr + np.less(arr1, scalar) Out[123]: array([2, 2, 2, 2, 2, 2, 1, 1]) 的解决方案。通过data.table3:5ID列(分数列)上找到最大值。

Group

数据:

library(data.table)
setDT(d)
d[, .(Max = do.call(max, .SD)), .SDcols = 3:5, .(ID, Group)]

   ID Group Max
1: a1   abc  11
2: a1   def   5
3: a2   def  11

答案 1 :(得分:3)

使用tidyverse的解决方案。

library(tidyverse)

dat2 <- dat1 %>%
  gather(Column, Value, starts_with("Score")) %>%
  group_by(ID, Group) %>%
  summarise(Max = max(Value)) %>%
  ungroup()
dat2
# # A tibble: 3 x 3
#   ID    Group   Max
#   <fct> <fct> <dbl>
# 1 a1    abc      11
# 2 a1    def       5
# 3 a2    def      11

答案 2 :(得分:1)

还有tidyverse

的其他几个选项
library(tidyverse)
df1 %>%
     group_by(ID, Group) %>% 
     nest %>% 
     mutate(Max = map_dbl(data, ~ max(unlist(.x)))) %>% 
     select(-data)

或使用pmax

df1 %>% 
    mutate(Max = pmax(!!! rlang::syms(names(.)[3:5]))) %>% 
    group_by(ID, Group) %>% 
    summarise(Max = max(Max))
# A tibble: 3 x 3
# Groups:   ID [?]
#  ID    Group   Max
#  <fct> <fct> <dbl>
#1 a1    abc      11
#2 a1    def       5
#3 a2    def      11

或使用base R

aggregate(cbind(Max = do.call(pmax, df1[3:5])) ~ ID + Group, df1, max)

答案 3 :(得分:0)

这是使用nest的整洁解决方案:

library(tidyverse)
df %>%
  nest(-(1:2),.key="Max") %>%
  mutate_at("Max",map_dbl, max)
#   ID Group Max
# 1 a1   abc  11
# 2 a1   def   5
# 3 a2   def  11

在基数R中:

res <- aggregate(. ~ ID + Group,df,max)
res <- cbind(res[1:2], Max = do.call(pmax,res[-(1:2)]))
res
#   ID Group Max
# 1 a1   abc  11
# 2 a1   def   5
# 3 a2   def  11

答案 4 :(得分:0)

这是基本的R解决方案

example5

# gives 2x2 table
x <- by(df[, !names(df) %in% c("ID", "Group")], list(df$ID, df$Group), max)

# get requested format
tmp <- expand.grid(ID = rownames(x), Group = colnames(x))
tmp$Max <- as.vector(x)
tmp[complete.cases(tmp), ]
#R   ID Group Max
#R 1 a1   abc  11
#R 3 a1   def   5
#R 4 a2   def  11