Применить функцию ко всем парам в одной группе

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

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

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

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

На самом деле это не дубликат вопроса, который вы предоставили. Ему нужны суммы каждой пары в группе, а не сумма группы.

Adamm 30.05.2019 14:38

да, возобновил вопрос.

Ronak Shah 30.05.2019 14:41

Ой, извини. Пропустил это. Спасибо @RonakShah

Sotos 30.05.2019 14:45
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
3
175
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Мы можем splitValue для каждого 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

Я пытался сделать это сам, однако это не работает должным образом. Почему group_by() не работает в этом случае? data %>% group_by(Group) %>% {apply(combn(Value, m=2), 2, sum)}

Adamm 30.05.2019 15:35

@ Адамм, хммм ... Я не уверен, что использование apply будет правильным выбором здесь.

Ronak Shah 30.05.2019 16:02

Спасибо, это здорово! Однако я не могу понять, как изменить его для использования с моими дополнительными функциями, а не со встроенной суммой функций.

Helen 30.05.2019 16:20

@Helen, ты можешь использовать это как sapply(split(df$Value, df$Group), function(x) combn(x, 2, function(y) addnums(y[1], y[2])))

Ronak Shah 30.05.2019 16:25

Мы можем использовать группу по варианту с 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))

Спасибо, это работает хорошо, но для меня очень важно использовать функцию addnums, которую я определил, а не суммировать, есть ли способ добиться этого?

Helen 30.05.2019 16:27

@Helen Спасибо, я обновил пост. Я бы сохранил столбец информации о группе, чтобы правильно идентифицировать значения

akrun 30.05.2019 16:30

Другие вопросы по теме