2015-07-17 5 views
0

Я пытаюсь подмножество в паре данные на основе условий.
пара состоит из двух человек, наблюдаемых в течение 2 дней.R - Подмножество на основе условий для парных данных

Основные данные моего образца: 'hldid', 'cid', 'pid', 'diary', 'sex', 'day', 'main1'.

'hldid' относится к парному идентификатору данных,

'cid' это парный данные дня идентификатор

'pid' персонального идентификатор 'diary' дневника (каждым люди должны быть заполнены 2 дневников) 'sex' 'day' 'main1' относятся к пола, дня и наблюдаемых видов деятельности.

То, что я хотел бы сделать, это подмножество данных на основе 2-х условий:

  1. Данные должны быть в паре это означает, что hldid должно быть 2 лиц. Каждая пара должна быть сделана из мужчины и женщины.
  2. Физические лица должны заполнить 2 diary. Так 4 Дневник по hldid

Единственный способ я нашел, чтобы сделать это, чтобы сделать следующее:

Раздельное по полу

M = filter(dtaSimple, sex == 1) 
W = filter(dtaSimple, sex == 2) 

Merge по идентификатору в паре дней

dtaSimple_c = merge(M, W, by = 'cid', suffixes = c('_m', '_w')) 

Затем я получу

 cid hldid_m pid_m diary_m sex_m day_m main1_m hldid_w pid_w diary_w sex_w day_w main1_w 
1 1250_1 1250 1250_2  1  1  1  0 1250 1250_1  1  2  1  0 
2 1250_2 1250 1250_2  2  1  3  0 1250 1250_1  2  2  3  0 
3 1294_1 1294 1294_2  1  1  6  0 1294 1294_1  1  2  6  0 
4 1294_2 1294 1294_2  2  1  1  0 1294 1294_1  2  2  1  0 

Я думаю, что это не совсем удовлетворительно. Каждая строка относится к первому дневнику каждого hldid, и каждая колонка ссылается либо на мужчину, либо на женщин pair.

Я хотел был бы сохранить исходную структуру данных 1 линии один человек и один день.

hldid cid pid diary sex day main1 
1 1250 1250_1 1250_1  1 2 1  0 
2 1250 1250_2 1250_1  2 2 3  0 
3 1250 1250_1 1250_2  1 1 1  0 
4 1250 1250_2 1250_2  2 1 3  0 
..... 

данные:

dtaSimple = structure(
    list(
     hldid = c(1250, 1250, 1250, 1250, 1294, 1294, 1294, 1294, 1352, 1352), 
     cid = c("1250_1", "1250_2", "1250_1", "1250_2", "1294_1", "1294_2", "1294_1", "1294_2", "1352_1", "1352_2"), 
     pid = c("1250_1", "1250_1", "1250_2", "1250_2", "1294_1", "1294_1", "1294_2", "1294_2", "1352_1", "1352_1"), 
     diary = c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), 
     sex = c(2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L), 
     day = c(1L, 3L, 1L, 3L, 6L, 1L, 6L, 1L, 1L, 3L), 
     main1 = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)), 
    .Names = c("hldid", "cid", "pid", "diary", "sex", "day", "main1"), 
    row.names = c(NA, 10L), 
    class = "data.frame" 
) 

ответ

4

Похоже, вам нужно фильтровать переменную группировки. Насколько я понимаю, для каждого hldid вы хотите убедиться, что есть 2 различных значения для sex и всего 4 наблюдения.

Вы можете использовать filter и group_by из dplyr:

library(dplyr) 

dtaSimple %>% 
    group_by(hldid) %>% 
    filter(n_distinct(sex) == 2, n() >= 4) 

    hldid cid pid diary sex day main1 
1 1250 1250_1 1250_1  1 2 1  0 
2 1250 1250_2 1250_1  2 2 3  0 
3 1250 1250_1 1250_2  1 1 1  0 
4 1250 1250_2 1250_2  2 1 3  0 
5 1294 1294_1 1294_1  1 2 6  0 
6 1294 1294_2 1294_1  2 2 1  0 
7 1294 1294_1 1294_2  1 1 6  0 
8 1294 1294_2 1294_2  2 1 1  0 

Изменение набора данных так один hldid не имеет 4 наблюдения более тщательно проверить:

dtaSimple2 = dtaSimple[-4,] 

dtaSimple2 %>% 
    group_by(hldid) %>% 
    filter(n_distinct(sex) == 2, n() >= 4) 

    hldid cid pid diary sex day main1 
1 1294 1294_1 1294_1  1 2 6  0 
2 1294 1294_2 1294_1  2 2 1  0 
3 1294 1294_1 1294_2  1 1 6  0 
4 1294 1294_2 1294_2  2 1 1  0 

Если каждый sex сусло имеют 2 записи дневника, и один секс может иметь 1 запись, а другой может иметь 3 записи, вам потребуется немного другая стратегия. Может быть, просто убедитесь, что у вас есть более 2 наблюдений за каждые sex за каждые id?

dtaSimple %>% 
    group_by(hldid) %>% 
    filter(sum(sex == 1) >= 2, sum(sex == 2) >= 2) 
+0

ОК, когда я получаю зависание 'ddply', я попадаю в dplyr-фильтрацию. R такой классный! – aaryno

1

В plyr библиотеки есть функция ddply которая хороша для быстрой группировки и подведения комбинаций значений столбцов. Учитывая, что вам нужны очень конкретные подсчеты для группировок, мне нравится ddply. Эти цепи две ddply() функции вместе, чтобы в конечном счете отфильтровать лиц на основании: 1) они не имеют два значения дневника

# calculate the number of diaries by pid (we are looking for exactly two): 
diaryByPid <- ddply(dtaSimple,c("pid"),function(x){ length(unique(x$diary))}) 

# the valid pids have exactly two unique diary values 
validPid <- diaryByPid$pid[which(diaryByPid[,2]==2)] 

# now subset the original dtaSimple to retain only those matched above 
dtaSub <- dtaSimple[which(dtaSimple$pid %in% validPid),] 

Мы исключили записи, для которых были не два значения уникальный дневник ПИД-.Теперь нам нужно соединить их с их соответствующих cid значений и убедитесь, что представлены оба пола:

# ddply to group by cid and count the number of unique values of $sex column 
sexByCid <- ddply(dtaSub,c("cid"),function(x){ length(unique(x$sex))}) 

# retain the cids for which we have two unique sexes 
validCid <- sexByCid$cid[which(sexByCid[,2]==2)] 

# subset the previously subsetted dtaSub to remove records without gender matches. 
dtaSub2 <- dtaSub[which(dtaSub$cid %in% validCid),] 

Поскольку у нас есть только удаленные строки из исходной структуры, остается в том же формате:

head(dtaSub2) 
    hldid cid pid diary sex day main1 
1 1250 1250_1 1250_1  1 2 1  0 
2 1250 1250_2 1250_1  2 2 3  0 
3 1250 1250_1 1250_2  1 1 1  0 
4 1250 1250_2 1250_2  2 1 3  0 
5 1294 1294_1 1294_1  1 2 6  0 
6 1294 1294_2 1294_1  2 2 1  0 
7 1294 1294_1 1294_2  1 1 6  0 
8 1294 1294_2 1294_2  2 1 1  0 
Смежные вопросы