2013-06-23 3 views
1

Я пытаюсь создать агрегированный список пар (ключ, значение):R агрегат (ключ, значение) данных для каждой строки

d <- data.frame(key.1 = c(1,1), 
       val.1 = c(100,100), 
       key.2 = c(1,1), 
       val.2 = c(100,100), 
       key.3 = c(2,3), 
       val.3 = c(100,100)) 

key.1 val.1 key.2 val.2 key.3 val.3 
    1 100  1 100  2 100 
    1 100  1 100  3 100 

, и я хочу, чтобы результат:

key.1 val.1 key.2 val.2 
    1 200  2 100 
    1 200  3 100 

С учетом того, что (1,100) и (1,100) получают агрегированные данные на основе общего 1, а их значение суммируется до 200. (2100) в первой строке и (3,100) во 2-й строке остаются такими, какие они есть, так как нет общего ключа с другой парой.

В отличие от this question, В моем сценарии я должен заполнить каждую строку моего информационного кадра отдельно. В настоящее время я просто повторяю строки за строкой, и для каждой строки используется «aggregate». Есть ли более разумный способ сделать это?

+0

Можете ли вы 'dput' образец ваших данных. Это не очень четко сформулированный вопрос. – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto: добавлен образец. thx для предложения – zuuz

ответ

2

Вот решение, которое получает вас значения, которые вы ищете, хотя и в несколько ином формате, чем тот, который вы указали в примере вывода:

  1. Создать «ID», основанный на rownames, так как вы хотите, чтобы агрегировать по строкам, в конце концов ...

    d$ID <- rownames(d) 
    
  2. Преобразование данных из «широкий» в «длинный» формат с использованием reshape

    temp <- reshape(d, direction = "long", idvar="ID", 
           varying = setdiff(names(d), "ID")) 
    
    temp 
    #  ID time key val 
    # 1.1 1 1 1 100 
    # 2.1 2 1 1 100 
    # 1.2 1 2 1 100 
    # 2.2 2 2 1 100 
    # 1.3 1 3 2 100 
    # 2.3 2 3 3 100 
    
  3. Используйте aggregate, чтобы рассчитать сумму комбинацией строк (ID) и ключей (клавиш). Кроме того, создайте второй «ID» на основе «групп» исходных идентификаторов.

    temp1 <- aggregate(val ~ ID + key, temp, sum) 
    temp1 <- within(temp1, { 
        ID2 <- ave(ID, ID, FUN = seq_along) 
    }) 
    temp1 
    # ID key val ID2 
    # 1 1 1 200 1 
    # 2 2 1 200 1 
    # 3 1 2 100 2 
    # 4 2 3 100 2 
    
  4. Используйте reshape снова, чтобы вернуться к «широкой» форме:

    reshape(temp1, direction = "wide", idvar="ID", timevar="ID2") 
    # ID key.1 val.1 key.2 val.2 
    # 1 1  1 200  2 100 
    # 2 2  1 200  3 100 
    
+0

да, размер должен быть val. это опечатка. Что касается остальной части вашего ответа - я все еще читаю это. – zuuz

+1

@zorbar, Это воскресенье, и сейчас у меня нет работы, поэтому я буду щедр и даю полный ответ. – A5C1D2H2I1M1N2O1R2T1

+0

Большое спасибо, я сразу погружусь в ваш код. – zuuz

0

Для этого можно, данные первой потребности преобразования в формат «кругленькую». Каждый ключ и каждый вал фактически являются одной и той же переменной, и вы хотите агрегировать ключ и другую переменную, колонку, которая явно не закодирована. Эти данные должны быть организованы так:

d <- data.frame(key = c(1,1,1,1,2,3), 
      val = c(100,100,100,100,100,100), 
      keycol = c(1,1,2,2,3,3)) 

Что дает

key val keycol 
# 1 100  1 
# 1 100  1 
# 1 100  2 
# 1 100  2 
# 2 100  3 
# 3 100  3 

Теперь просто агрегат по key и keycol, чтобы получить желаемый результат. Мне нравится dplyr.

library(dplyr) 
d %>% group_by(key, keycol) %>% summarise(sum(val)) 

Это дает результат, который вы хотели, в правильной форме.

 key keycol sum(val) 
    (dbl) (dbl) (dbl) 
#1  1  1  200 
#2  1  2  200 
#3  2  3  100 
#4  3  3  100