2013-08-22 2 views
-3

У меня есть данные, которые выглядят следующим образом:Сумма несколько столбцов по группам

Time ColA ColB ColC 
0 1 10 5 
1 3 7 15 
2 0 8 9 
3 3 4 5 
4 4 5 6 
7 10 23 4 

я хотел бы, чтобы сгруппировать мои данные в интервалы времени одинакового размера и суммировать переменные каждый столбец. Это, например, было бы результат группирования времени на 2:

Time ColA ColB ColC 
0 4 17 20 
2 3 12 14 
4 4 5 6 
7 10 23 4 

Я мог бы маркировать данные, введя новый столбец, значение которого floor(data$Time/2), но неясно, как сделать сложения. Большинство пакетов, которые я смотрел на , показывают, чтобы суммировать только один столбец, тогда как я хотел бы суммировать все столбцы.

+0

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

+0

Действительно, @DWin. К сожалению, во многих случаях эти ответы либо слишком специфичны, либо не имеют объяснения рабочих частей. – Richard

+0

Не дубликат, @ Ferdinand.kraft. Этот ответ, кажется, объединяет несколько столбцов в один, тогда как я бы хотел, чтобы мои столбцы оставались раздельными. – Richard

ответ

5

Используйте пакет «data.table»! Синтаксис намного проще, а время работы быстрее.

### Load package 
require(data.table) 

### Set up variables; Create data.table 
time <- c(0:4, 7) 
ColA <- c(1, 3, 0, 3, 4, 10) 
ColB <- c(10, 7, 8, 4, 5, 23) 
ColC <- c(5, 15, 9, 5, 6, 4) 
data <- data.table(time, ColA, ColB, ColC) 

### Determine which columns we want to apply the function to 
sum.cols <- grep("Col", names(data), value = T) 

### Sum each column within each group 
data[, lapply(.SD, sum), by = floor(time/2), .SDcols = sum.cols] 

### Output: 
    floor ColA ColB ColC 
1:  0 4 17 20 
2:  1 3 12 14 
3:  2 4 5 6 
4:  3 10 23 4 

Обратите внимание, что символ «.SD» относится к «подмножеству данных». В этом случае функция lapply выполняет итерацию по столбцам таблицы данных, применяя функцию «сумма» к каждому столбцу. В каждом столбце суммы вычисляются для каждого уровня нашей переменной «floor».

+1

вам не нужно создавать отдельную переменную: 'data [, lapply (.SD, sum), by = floor (time/2)] ' – eddi

+0

молодец, вы меня избили, это, безусловно, путь – statquant

+1

Всегда приятно создавать ненужные переменные, спасибо @eddi! – Andreas

0

Только для потомков это подход «plyr» для решения вопроса OP. Единственное реальное преимущество использования функций «plyr» над функциями «data.table» заключается в том, что вы можете использовать объекты, отличные от data.table.

Setup: Во-первых, здесь есть данные использовать:

data <- read.table(text=" 
    Time ColA ColB ColC 
    0 1 10 5 
    1 3 7 15 
    2 0 8 9 
    3 3 4 5 
    4 4 5 6 
    7 10 23 4 
    ", header=TRUE) 

Ply-он: Вот ввода кадра данных (d) и вывода кадра данных (d), так что мы «Используйте функцию« ddply ».

ddply(
    data[, -1], 
    .(Time=floor(data$Time/2)), 
    colSums) 

    # Time ColA ColB ColC 
    # 1 0 4 17 20 
    # 2 1 3 12 14 
    # 3 2 4 5 6 
    # 4 3 10 23 4 

Мы говорим «ddply» использовать переменную «данные» для данных (минус первый столбец, который содержит время), упорядочивание по floor(data$Time/2), и создать столбцы с суммами остального столбцы, запустив функцию «colSums» над каждой группой строк.

2

Просто, чтобы продемонстрировать «дублированный» звонок Фердинанда.Карфт правильный и, возможно, ближе к тому, что было запрошено, включая запрос на просмотр интервалов, создаваемых в исходных единицах.

> aggregate(data[-1], list(cut(data$Time, include.lowest=TRUE, 
          right=FALSE, breaks=seq(range(data$Time)[1], 
                range(data$Time)[2]+1, 
                by=2))) , 
         sum) 

    Group.1 ColA ColB ColC 
1 [0,2) 4 17 20 
2 [2,4) 3 12 14 
3 [4,6) 4 5 6 
4 [6,8] 10 23 4 
Смежные вопросы