2014-12-04 3 views
0

У меня есть маленький (2k) набор данных, содержащий ответы на вопросники, заполненные студентами, которые были отбираются дважды в год. не все студенты, которые присутствовали на первой волне, были там для второй волны и наоборот. для каждого ученика был создан уникальный идентификатор, который состоял из школьного кода, кода класса, номера ученика и волны в виде десятичной точки. например, 100612.1 - студент из школы 10, класс 6, 12 в списке имен, и это была первая волна. идея десятичной точки была способом снова идентифицировать одного и того же ученика в наборе данных (единственное значение, которое отличается от abs (1) от данного id, является одним и тем же учеником на другой волне). По крайней мере, это было идея.нахождение «почти» индексов дубликатов в таблице данных и вычисление дельта

я думал о сценарии, который будет делать следующее: - найти строки, которые уникальный идентификатор меньше абс (1) друг от друга - для тех строк, генерировать новую строку (в новой таблице) который состоит из идентификатора студента и дельта измеренных переменных (т. е. значения в волне 2 - значение в волне 1).

Я новичок в R, но у меня крошечный бит фона в другом ООП. Я думал о создании цикла for, который работает от 1 до длины (df) и просто ищет его «брат». мое чувство кишки подсказывает мне, что это не так, как в Р. делаются какие-то идеи? все, что мне нужно, - это быстрый способ просеивания данных, ищущих вторую волновую строку. Я думаю, что остальное должно быть прямо оттуда.

спасибо, что Вам помогли

PS. так как это мой первый пост здесь, я заранее извиняюсь за любые нарушения в этом сообщении ... :)

+0

отрубить десятичную величину и вычислить итоговую статистику (т. Е. Дельта) на оставшийся идентификатор (100612) – rawr

ответ

0

Вопрос ссылается на data.table, поэтому здесь можно адаптировать ответ @ jed с помощью этого пакета.

ids <- c(100612.1,100612.2,100613.1,100613.2,110714.1,201802.2) 
answers <- c(5,4,3,4,1,0) 

Пример данных, как и раньше, теперь вместо data.frame и tapply вы можете сделать это:

library(data.table) 

surveyDT <- data.table(ids, answers) 

surveyDT[, `:=` (child = substr(ids, 1, 6), wave = substr(ids, 8, 8))] # split ID's 
# note multiple assign-by-reference := syntax above 
setkey(surveyDT, child, wave) # order data 

# calculate delta on keyed data, grouping by child 
surveyDT[, delta := diff(answers), by = child] 

unique(surveyDT[, delta, by = child]) # list results 
    child delta 
1: 100612 -1 
2: 100613  1 
3: 110714 NA 
4: 201802 NA 

Для удаления строк со значениями NA для дельта:

unique(surveyDT[, .SD[(!is.na(delta))], by = child]) 
    child  ids answers wave delta 
1: 100612 100612.1  5 1 -1 
2: 100613 100613.1  3 1  1 

Использование .SDcols для вывода только конкретные столбцы (в дополнение к столбцам by), например,

unique(surveyDT[, .SD[(!is.na(delta))], by = child, .SDcols = 'delta']) 
    child delta 
1: 100612 -1 
2: 100613  1 

Мне понадобилось некоторое время, чтобы познакомиться с синтаксисом data.table, но теперь я нахожу его более интуитивно понятным и быстрым для больших данных.

+0

спасибо! быстро последующие вопросы, если вы не возражаете: - нет необходимости в substr, так как я могу создать дочерний ID без использования волны. я прав? - если мне нужно вычитать несколько столбцов, я могу рассчитать все сразу? surveyDT [, delta1: = diff (ответы), delta2: = diff (answers2), by = child] что-то вдоль этих строк? - есть ли способ отфильтровать результаты, которые не имели двух волн? Я думал об использовании complete.cases .. еще раз, спасибо !! – isomitzi

+0

, если вы разместите пример своего набора данных в своем вопросе, этот тип вопросов будет намного легче ответить. – jed

+0

'complete.cases' может работать здесь, но обратите внимание, что удаляет строки с NA в любом столбце. См. Отредактированный ответ для способа фильтрации NA из определенных столбцов. Re: вычисления в нескольких столбцах, следуйте примеру, когда я использовал ': =' с backticks, чтобы назначить child и wave в примере. Подробнее см. 'Help (': =')'. – Scott

0

Есть два способа, которые приходят на ум. Проще всего использовать функцию пола(), которая возвращает целое число, например:

floor(100612.1) 
#[1] 100612 

floor(9.9) 
#[1] 9 

В качестве альтернативы, вы можете написать довольно простое выражение регулярного выражения, чтобы избавиться от десятичных тоже. Затем вы можете использовать unique(), чтобы найти строки, которые являются или не дублируются.

0

позволяет сделать некоторые поддельные данные, чтобы мы могли видеть нашу проблему легко:

ids <- c(100612.1,100612.2,100613.1,100613.2,110714.1,201802.2) 
answers <- c(5,4,3,4,1,0) 
survey <- data.frame(ids,answers) 

Теперь давайте разделить наши идентификаторы в двух разных колонках:

survey$child_id <- substr(survey$ids,1,6) 
survey$wave_id <- substr(survey$ids,8,8) 

Тогда мы закажем на ребенка и волны и вычислить различия на основе ребенка:

survey[order(survey$child_id, survey$wave_id),] 
survey$delta <- unlist(tapply(survey$answers, survey$child_id, function(x) c(NA,diff(x)))) 

Выход:

 ids answers child_id wave_id delta 
1 100612.1  5 100612  1 NA 
2 100612.2  4 100612  2 -1 
3 100613.1  3 100613  1 NA 
4 100613.2  4 100613  2  1 
5 110714.1  1 110714  1 NA 
6 201802.2  0 201802  2 NA 
+0

спасибо! Я запустил код в R, чтобы продолжить. уникальный идентификатор был создан из существующих переменных в данных. т.е. у меня есть «волновая» переменная. теперь, когда я вижу ваше предложение, не будет ли ключ к «child, wave» делать то же самое? также, последний из вашего кода немного нечеткий для меня ... еще раз, спасибо за быстрый повтор! это отличные идеи. – isomitzi

+0

@isomitzi все, что я делаю в последнем бите кода ... Если у ребенка есть ответ в обеих волнах, я вычитаю счет в первой волне из оценки во второй волне. поэтому у ребенка 100612 было 5 в волне 1 и 4 в волне 2, поэтому его дельта -1. – jed

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