объединение строк фреймов данных

У меня есть фрейм данных с двумя переменными идентификатора и переменной имени. Существует различное неравное количество комбинаций этих переменных.

## dput'ed data.frame
df <- structure(list(V1 = structure(c(1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 
4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L), .Label = c("A", 
"B", "C", "D", "E"), class = "factor"), V2 = c(1L, 2L, 3L, 1L, 
2L, 3L, 2L, 2L, 1L, 3L, 1L, 2L, 1L, 3L, 2L, 1L, 1L, 3L, 1L, 1L
), V3 = structure(c(1L, 2L, 3L, 1L, 2L, 3L, 2L, 2L, 1L, 3L, 1L, 
2L, 1L, 3L, 2L, 1L, 1L, 3L, 1L, 1L), .Label = c("test1", "test2", 
"test3"), class = "factor")), .Names = c("V1", "V2", "V3"), class = "data.frame", row.names = c(NA, 
-20L))
>df
   V1 V2    V3
1   A  1 test1
2   B  2 test2
3   C  3 test3
4   D  1 test1
5   E  2 test2
6   A  3 test3
7   B  2 test2
8   C  2 test2
9   D  1 test1
10  E  3 test3
11  A  1 test1
12  B  2 test2
13  C  1 test1
14  D  3 test3
15  E  2 test2
16  A  1 test1
17  B  1 test1
18  C  3 test3
19  D  1 test1
20  E  1 test1

Я хочу объединить строки, чтобы результат имел только одну запись для каждой V1, а затем список значений, разделенных запятыми, в качестве второй и третьей переменных. Вот так:

  f    V2            V3
1 A    1 ,3 ,1 ,1    test1 ,test3 ,test1 ,test1
2 B    2 ,2 ,2 ,1    test2 ,test2 ,test2 ,test1
3 C    3 ,2 ,1 ,3    test3 ,test2 ,test1 ,test3
4 D    1 ,1 ,3 ,1    test1 ,test1 ,test3 ,test1
5 E    2 ,3 ,2 ,1    test2 ,test3 ,test2 ,test1

Я пробовал это со следующим кодом, который хорош, если немного медленный. Любые предложения для более быстрого решения?

df = lapply(levels(df$V1), function(f){
  cbind(f,
        paste(df$V2[df$V1==f],collapse=" ,"),
        paste(df$V3[df$V1==f],collapse=" ,"))
})
df = as.data.frame(do.call(rbind, df))
df

Изменить: исправлен dput(df)


person Davy Kavanagh    schedule 10.07.2012    source источник
comment
Похоже, вы dput получили желаемые результаты, а не данные, которые нужно преобразовать.   -  person Josh O'Brien    schedule 10.07.2012
comment
Прости за это. Должно быть исправлено сейчас   -  person Davy Kavanagh    schedule 10.07.2012
comment
Вам нужна только скорость? Ваш вывод также несколько ограничивает данные, сводя все эти значения в одну строку символов. Использование aggregate позволяет избежать этого; каждый столбец в выводе представляет собой список, из которого вы можете легко вернуться к своему предыдущему формату данных.   -  person A5C1D2H2I1M1N2O1R2T1    schedule 10.07.2012
comment
Я этого не осознавал. Спасибо, так как возможность вернуться удобна.   -  person Davy Kavanagh    schedule 10.07.2012


Ответы (1)


Убедитесь, что V3 (или другие факторные переменные) находятся в режиме as.character и используйте aggregate:

df$V3 = as.character(df$V3)
aggregate(df[-1], by=list(df$V1), c, simplify=FALSE)
#   Group.1         V2                         V3
# 1       A 1, 3, 1, 1 test1, test3, test1, test1
# 2       B 2, 2, 2, 1 test2, test2, test2, test1
# 3       C 3, 2, 1, 3 test3, test2, test1, test3
# 4       D 1, 1, 3, 1 test1, test1, test3, test1
# 5       E 2, 3, 2, 1 test2, test3, test2, test1
person A5C1D2H2I1M1N2O1R2T1    schedule 10.07.2012