2014-02-12 1 views
4

В нижеприведенном data.table у меня есть информация о составе команд, участвующих в проектах. Переменная id сообщает идентификатор команды, в то время как переменная event дает номер проекта. Переменная freqrel описывает состав команд (вы можете видеть, что freqrel составляет до 1 в каждой команде).Вложенные группировки с данными. Таблица

structure(list(id = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 
4L, 4L, 5L, 5L, 5L), event = c("127b", "127b", "127b", "127b", 
"127b", "127b", "127b", "127b", "127b", "125t", "125t", "125t", 
"125t", "125t", "125t"), membr = c("engineer", "mathematician", 
"physicist", "mathematician", "physicist", "surgeon", "dentist", 
"mathematician", "programmer", "physicist", "sociologist", "surgeon", 
"musician", "sociologist", "surgeon"), freqrel = c(0.4, 0.4, 
0.2, 0.166666666666667, 0.5, 0.333333333333333, 0.333333333333333, 
0.5, 0.166666666666667, 0.75, 0.125, 0.125, 0.444444444444444, 
0.444444444444444, 0.111111111111111)), .Names = c("id", "event", 
"membr", "freqrel"), row.names = c(NA, -15L), class = c("data.table", 
"data.frame"), sorted = c("id", "event"), .internal.selfref = <pointer: 0x039a24a0>) 

Как я вижу, данные разделены на вложенные группы. Первое разделение происходит на уровне проекта (прямая линия), а второе - на уровне команды (пунктирная линия).

id event   membr freqrel 
1: 1 127b  engineer 0.4000000 
2: 1 127b mathematician 0.4000000 
3: 1 127b  physicist 0.2000000 
-------------------------------------- 
4: 2 127b mathematician 0.1666667 
5: 2 127b  physicist 0.5000000 
6: 2 127b  surgeon 0.3333333 
-------------------------------------- 
7: 3 127b  dentist 0.3333333 
8: 3 127b mathematician 0.5000000 
9: 3 127b programmer 0.1666667 
_____________________________________ 
10: 4 125t  physicist 0.7500000 
11: 4 125t sociologist 0.1250000 
12: 4 125t  surgeon 0.1250000 
-------------------------------------- 
13: 5 125t  musician 0.4444444 
14: 5 125t sociologist 0.4444444 
15: 5 125t  surgeon 0.1111111 

Из этого начального состояния я хотел бы сделать команды в рамках этого же проекта вполне сопоставимы, добавив к каждому из них также в membr типов, что команда не показывает, назначая их freqrel = 0. Результат должен быть таким:

id event   membr freqrel 
1: 1 127b  dentist 0.0000000 
2: 1 127b  engineer 0.4000000 
3: 1 127b mathematician 0.4000000 
4: 1 127b  physicist 0.2000000 
5: 1 127b programmer 0.0000000 
6: 1 127b  surgeon 0.0000000 
-------------------------------------- 
7: 2 127b  dentist 0.0000000 
8: 2 127b  engineer 0.0000000 
9: 2 127b mathematician 0.1666667 
10: 2 127b  physicist 0.5000000 
11: 2 127b programmer 0.0000000 
12: 2 127b  surgeon 0.3333333  
-------------------------------------- 
13: 3 127b  dentist 0.3333333 
14: 3 127b  engineer 0.0000000 
15: 3 127b mathematician 0.5000000 
16: 3 127b  physicist 0.0000000 
17: 3 127b programmer 0.1666667 
18: 3 127b  surgeon 0.0000000 
_____________________________________ 
19: 4 125t  musician 0.0000000 
20: 4 125t  physicist 0.7500000 
21: 4 125t sociologist 0.1250000 
22: 4 125t  surgeon 0.1250000 
-------------------------------------- 
23: 5 125t  musician 0.4444444 
24: 5 125t  physicist 0.0000000 
25: 5 125t sociologist 0.4444444 
26: 5 125t  surgeon 0.1111111 

Другими словами, после разделения данных с помощью byevent в качестве ключа, мне нужно разделить второй раз и сравнить массивы данных, полученных с помощью второго расщепления. Но здесь проблема в том, что я не знаю, как ссылаться на первый фрагмент, полученный с помощью by, а затем, как разделить снова и выполнить сравнения между частями базы данных. У вас есть идея, как я могу разобраться в этом?

Я был бы очень благодарен, если бы вы могли мне помочь. В самом деле.

ответ

4

Вот простой способ:

setkey(dt, id, membr) 
ans <- dt[, .SD[CJ(unique(id), unique(membr))], by=list(event)] 

Затем, вы можете просто заменить NA с 0, как показано ниже:

ans[is.na(freqrel), freqrel := 0.0] 

Некоторые объяснения: Ваша задача сводится к следующему - для каждый event, вы хотите, чтобы все возможные комбинации id, membr, чтобы вы могли выполнить соединение на этой все-комбинации wi тонкий, что группировка с использованием .SD.

Итак, первая группа у нас по event, и в том, что мы сначала получить все комбинации id, membr с помощью CJ (который будет иметь набор ключей для всех столбцов по умолчанию). Однако для выполнения соединения нам необходимо установить ключ для .SD. Поэтому мы устанавливаем key для dt в id, membr. Таким образом, мы выполняем объединение внутри каждой группы и даем вам предполагаемый результат. Надеюсь это немного поможет.

+0

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

+0

Это очень помогло. Это было отличное решение, и я рад, что задал вопрос, потому что ваш ответ заставил меня понять, что я никогда бы не сделал это в одиночку. Большое спасибо. Отличный урок стиля кодирования. – Riccardo

+0

@Arun @ Riccardo: Я вижу, что это больше месяца, но у меня есть два комментария, которые, я думаю, могут быть важны. Во-первых, '.SD [CJ()]' часть работает по назначению только потому, что по умолчанию 'nomatch = NA'. Можете указать, что он явно должен быть безопасным, если значение по умолчанию когда-либо изменено ... Во-вторых, учитывая способ его использования ** внутри ** '.SD',' unique() 'включает только значения' id' и 'мембрана', которые обнаруживаются ** после **, таблица данных была поднабором в соответствии с' by = ', а не во всей таблице данных.Это может быть предполагаемое поведение здесь (разные наборы «мембран» для каждого «события»), но, возможно, нет. – Peter

Смежные вопросы