Я хочу применить функцию ко всем парам элементов в одной группе, например,

Пример ввода:

Group  Item   Value  
A      1       89   
A      2       76  
A      3       2  
B      4       21  
B      5       10  

Желаемый результат - это вектор вывода функции для всех элементов в одной группе.

Например ради аргументов, если функция была:

addnums=function(x,y){  
  x+y  
}

Тогда желаемый результат будет:

165, 91, 78, 31

Я попытался сделать это с помощью суммирования в пакете dplyr, но это можно использовать только в том случае, если на выходе есть одно значение.

4
Helen 30 Май 2019 в 15:29

2 ответа

Лучший ответ

Мы можем split Value для каждого Group, а затем использовать combn для вычисления sum для каждой пары.

sapply(split(df$Value, df$Group), combn, 2, sum)

#$A
#[1] 165  91  78

#$B
#[1] 31

При необходимости в качестве одного вектора мы можем использовать unlist.

unlist(sapply(split(df$Value, df$Group), combn, 2, sum), use.names = FALSE)
#[1] 165  91  78  31

Если вы заинтересованы в tidyverse решении с использованием той же логики, мы можем сделать

library(dplyr)
library(purrr)

df %>%
  group_split(Group) %>%
  map(~combn(.x %>% pull(Value), 2, sum)) %>% flatten_dbl

#[1] 165  91  78  31
4
Ronak Shah 30 Май 2019 в 13:00

Мы можем использовать группу по выбору с data.table

library(data.table)
setDT(df1)[, combn(Value, 2, FUN = sum), Group]
#   Group  V1
#1:     A 165
#2:     A  91
#3:     A  78
#4:     B  31

Если мы хотим использовать addnums из поста ОП

setDT(df1)[, combn(Value, 2, FUN = function(x) addnums(x[1], x[2])), Group]
 #  Group  V1
#1:     A 165
#2:     A  91
#3:     A  78
#4:     B  31

Или используя tidyverse

library(dplyr)
library(tidyr)
df1 %>% 
  group_by(Group) %>%
  summarise(Sum = list(combn(Value, 2, FUN = sum)))  %>% 
  unnest
# A tibble: 4 x 2
#  Group   Sum
#  <chr> <int>
#1 A       165
#2 A        91
#3 A        78
#4 B        31

Используя addnums

df1 %>% 
 group_by(Group) %>%
 summarise(Sum = list(combn(Value, 2, FUN = 
         function(x) addnums(x[1], x[2])))) %>% 
 unnest

Или используя base R с aggregate

aggregate(Value ~ Group, df1, FUN = function(x) combn(x, 2, FUN = sum))

Данные

df1 <- structure(list(Group = c("A", "A", "A", "B", "B"), Item = 1:5, 
    Value = c(89L, 76L, 2L, 21L, 10L)), class = "data.frame", row.names = c(NA, 
-5L))
2
akrun 30 Май 2019 в 14:30