Объединить данные в одном столбце на основе значений в другом столбце - PullRequest
10 голосов
/ 27 сентября 2011

Я знаю, что есть простой способ сделать это ... но я не могу понять это.

В моем R-скрипте есть фрейм данных, который выглядит примерно так:

A      B    C
1.2    4    8
2.3    4    9
2.3    6    0
1.2    3    3
3.4    2    1 
1.2    5    1

Обратите внимание, что A, B и C являются именами столбцов. И я пытаюсь получить переменные, как это:

sum1 <- [the sum of all B values such that A is 1.2]
num1 <- [the number of times A is 1.2]

Есть ли простой способ сделать это? В основном я хочу получить фрейм данных, который выглядит следующим образом:

    A     num     totalB
   1.2    3       12
   etc    etc     etc

Где «num» - это количество раз, когда появилось конкретное значение A, а «totalB» - сумма значений B, заданных значением A.

Ответы [ 4 ]

18 голосов
/ 27 сентября 2011

Я бы использовал aggregate, чтобы получить два агрегата, а затем merge их в один фрейм данных:

> df
    A B C
1 1.2 4 8
2 2.3 4 9
3 2.3 6 0
4 1.2 3 3
5 3.4 2 1
6 1.2 5 1

> num <- aggregate(B~A,df,length)
> names(num)[2] <- 'num'

> totalB <- aggregate(B~A,df,sum)
> names(totalB)[2] <- 'totalB'

> merge(num,totalB)
    A num totalB
1 1.2   3     12
2 2.3   2     10
3 3.4   1      2
5 голосов
/ 27 сентября 2011

Вот решение с использованием пакета plyr

plyr::ddply(df, .(A), summarize, num = length(A), totalB = sum(B))
4 голосов
/ 09 июня 2017

В dplyr:

library(tidyverse)
A <- c(1.2, 2.3, 2.3, 1.2, 3.4, 1.2)
B <- c(4, 4, 6, 3, 2, 5)
C <- c(8, 9, 0, 3, 1, 1)

df <- data_frame(A, B, C)

df %>%
    group_by(A) %>% 
    summarise(num = n(),
              totalB = sum(B))
4 голосов
/ 13 сентября 2012

Вот решение, использующее data.table для экономии памяти и времени.

library(data.table)
DT <- as.data.table(df)
DT[, list(totalB = sum(B), num = .N), by = A]

Для поднабора только тех строк, где C==1 (согласно комментарию к @aix answer)

DT[C==1, list(totalB = sum(B), num = .N), by = A]
...