Как искать и суммировать несколько столбцов в R - PullRequest
4 голосов
/ 18 октября 2019

Предположим, у меня есть две структуры данных, структурированные так:

ГРУППЫ:

P1      P2      P3      P4
123     213     312     231
345     123     213     567

INDIVIDUAL_RESULTS:

ID      SCORE
123     23
213     12
312     11
213     19
345     10
567     22

Я хочу добавить столбец к GROUPS который является суммой каждого из их отдельных результатов:

P1      P2      P3      P4      SCORE
123     213     312     231     65

Я пытался использовать различные merge методы, но на самом деле только что создал беспорядок. Я чувствую, что есть простое решение, о котором я просто не знаю, было бы очень признательно за руководство!

Ответы [ 3 ]

6 голосов
/ 18 октября 2019
d1=read.table(text="
P1      P2      P3      P4
123     213     312     231
345     123     213     567",h=T)

d2=read.table(text="
ID      SCORE
123     23
213     12
312     11
231     19
345     10
567     22",h=T)

Я буду использовать функции apply и match. Apply будет применять функцию match к каждой строке d1, match найдет совпадающие значения из строки d1 и d2 $ ID (их индексы), а затем примет значения в d2 $ SCORE по этим индексам. В итоге мы их суммируем.

d1$SCORE=apply(d1,1,function(x){
  sum(d2$SCORE[match(x,d2$ID)])
})

и результат

   P1  P2  P3  P4 SCORE
1 123 213 312 231    65
2 345 123 213 567    67
1 голос
/ 18 октября 2019

Я бы попробовал медленно, но мог бы быть интуитивно понятным способом для новых пользователей. Я думаю, что сложность была создана форматом ваших данных d1. Если вы немного поправите:

library(tidyverse)
d1<-data.frame(t(d1))
colnames(d1) <-c("group1", "group2")
d1$P = row.names(d1)
d1<-d1 %>% 
  pivot_longer(
    cols = group1:group2, 
    names_to = "Group",
    values_to = "ID"
  )  

df <-left_join(d1, d2, by ="ID")
df

# A tibble: 8 x 4
  P     Group     ID SCORE
  <chr> <chr>  <int> <int>
1 P1    group1   123    23
2 P1    group2   345    10
3 P2    group1   213    12
4 P2    group2   123    23
5 P3    group1   312    11
6 P3    group2   213    12
7 P4    group1   231    19
8 P4    group2   567    22

Как только вы получите данные в этом более «традиционном» формате, мы легко сможем найти решение tidyverse.

df  %>% 
  group_by(Group) %>% 
  summarize(SCORE = sum(SCORE))
# A tibble: 2 x 2
  Group  SCORE
  <chr>  <int>
1 group1    65
2 group2    67
0 голосов
/ 18 октября 2019

Другая возможность - переформатировать первый data.frame, чтобы он содержал информацию о группе и подгруппе:

groups <- tidyr::gather(d1,name,number,P1:P4)

Эта информация может быть добавлена ​​ко второму data.frame и может в дальнейшем использоваться для различных анализов. Такие как скопления.

d2_groups <- merge(groups, d2, by.x = "number",by.y = "ID")

aggregate(d2_groups$SCORE,  by=list(groups = d2_groups$name), FUN=sum)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...