2013-05-27 2 views
3

У меня есть данные о времени реакции и точности, которые нужно оценивать для каждого объекта, и я хочу знать, какой пакет или функции R наилучшим образом отвечают моим потребностям. Ниже приведен фрагмент того, что данные выглядят для 2 предметов. Каждая строка представляет собой одно испытание, в котором субъект реагирует на стимул.Как вычислить переменные для каждого объекта в наборе данных

date subject trialn blockcode  trialtype latency response correct 
32913  15  1 practice taskswitch 1765  205  1 
32913  15  2 practice  cueswitch 4372  203  1 
32913  15  3 practice cuerepetition 2523  203  0 
32913  15  1  test  cueswitch 2239  205  1 
32913  15  2  test cuerepetition 1244  203  1 
32913  15  3  test taskswitch 1472  203  0 
32913  15  4  test  cueswitch 1877  205  1 
32913  15  5  test taskswitch 2271  203  1 
30413  16  1 practice taskswitch 1377  203  1 
30413  16  2 practice taskswitch 1648  203  1 
30413  16  3 practice  cueswitch 1181  205  1 
30413  16  1  test  cueswitch 1045  205  1 
30413  16  2  test cuerepetition  969  203  0 
30413  16  3  test  cueswitch  857  203  1 
30413  16  4  test taskswitch 1038  205  1 
30413  16  5  test cuerepetition  836  203  0 

Вот описание того, что я хотел бы сделать:

  • Глядя только на «тестовых» испытаний, по каждому предмету, вычислить
    • общее число испытаний
    • количество испытаний с задержками (т.е. время реакции) ниже 300 мс
    • средняя латентность
    • среднее значение
  • Затем, глядя только на испытаниях с латентными в пределах 3 стандартных отклонений от среднего времени ожидания субъекта, вычислить среднюю задержку для каждого trialtype
  • И наконец, создать новый фрейм данных со всеми этими переменными и предметным ID и date

ответ

3

Stackoverflow это на самом деле не предназначен для учебников, поэтому убедитесь, чтобы проверить большой интернет-ресурсов о data.table. website хорошее начало и есть много вопросов о пакете здесь на SO, которые покрывают почти все.

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

Во-первых, давайте загрузить пакет и читать в ваших данных:

library(data.table) 
str <- "date subject trialn blockcode  trialtype latency response correct 
     32913  15  1 practice taskswitch 1765  205  1 
     32913  15  2 practice  cueswitch 4372  203  1 
     32913  15  3 practice cuerepetition 2523  203  0 
     32913  15  1  test  cueswitch 2239  205  1 
     32913  15  2  test cuerepetition 1244  203  1 
     32913  15  3  test taskswitch 1472  203  0 
     32913  15  4  test  cueswitch 1877  205  1 
     32913  15  5  test taskswitch 2271  203  1 
     30413  16  1 practice taskswitch 1377  203  1 
     30413  16  2 practice taskswitch 1648  203  1 
     30413  16  3 practice  cueswitch 1181  205  1 
     30413  16  1  test  cueswitch 1045  205  1 
     30413  16  2  test cuerepetition  969  203  0 
     30413  16  3  test  cueswitch  857  203  1 
     30413  16  4  test taskswitch 1038  205  1 
     30413  16  5  test cuerepetition  836  203  0" 
DT <- as.data.table(read.table(text=str, header=TRUE)) 

Теперь это одна вещь, которую вы просили:

Глядя только на «тестовых» испытаний, для каждого уникальный объект вычисляет общее количество испытаний, количество испытаний с задержками (т. е. времени реакции) ниже 300 мс, средняя средняя задержка (то есть точность ).

DT[blockcode=="test", 
    list(TotalNr = .N, 
     NrTrailLat = sum(latency < 300), 
     MeanLat = mean(latency), 
     MeanCor = mean(correct)), 
    by="subject"] 
subject TotalNr NrTrailLat MeanLat MeanCor 
1:  15  5   0 1820.6  0.8 
2:  16  5   0 949.0  0.6 

В основном, с тех нескольких строк кода я мог бы ответить на все эти вопросы. И, на мой взгляд, синтаксис довольно прост. Для наших DT мы хотим посмотреть только наблюдения, где blockcode=="test". Затем мы хотим провести весь анализ по каждому вопросу отдельно. Это легко сделать с помощью заявления by="subject". Крутая вещь: если вы хотите разделить на несколько измерений, просто добавьте их ...Вместо игнорировании практики, давайте рассмотрим их по отдельности:

DT[, 
    list(TotalNr = .N, 
     NrTrailLat = sum(latency < 300), 
     MeanLat = mean(latency), 
     MeanCor = mean(correct)), 
    by="subject,blockcode"] 
    subject blockcode TotalNr NrTrailLat MeanLat MeanCor 
1:  15 practice  3   0 2886.667 0.6666667 
2:  15  test  5   0 1820.600 0.8000000 
3:  16 practice  3   0 1402.000 1.0000000 
4:  16  test  5   0 949.000 0.6000000 

Теперь не говорите мне, что это не здорово!

Давайте попробуем еще один:

Кроме того, создавать переменные, содержащие последний (или первый) значение даты и subjectID (это для того, чтобы поместить данные и subjectID в новой dataframe).

Я не уверен, что вы имеете в виду здесь именно потому, что date не изменяется в вашем примере для каждого предмета. Поэтому давайте сделаем это немного сложнее. Скажем, мы хотим знать латентность для каждой комбинации subject,blockcode для первого испытания. Для этого сначала нужно отсортировать DT так, чтобы мы знали, что первый trialn всегда 1. (Это не обязательно для этих экзаменационных данных, потому что оно уже отсортировано).

setkey(DT, subject, blockcode, trialn) 
DT[, list(FirstLat = latency[1]) , by="subject,blockcode"] 
subject blockcode FirstLat 
1:  15 practice  1765 
2:  15  test  2239 
3:  16 practice  1377 
4:  16  test  1045 

Однако, вы хотите добавить это как новый столбец в DT. Для этого вы можете использовать := оператор:

DT[, FirstLat := latency[1] , by="subject,blockcode"] 
DT 
date subject trialn blockcode  trialtype latency response correct FirstLat 
1: 32913  15  1 practice taskswitch 1765  205  1  1765 
2: 32913  15  2 practice  cueswitch 4372  203  1  1765 
3: 32913  15  3 practice cuerepetition 2523  203  0  1765 
4: 32913  15  1  test  cueswitch 2239  205  1  2239 
5: 32913  15  2  test cuerepetition 1244  203  1  2239 
6: 32913  15  3  test taskswitch 1472  203  0  2239 
7: 32913  15  4  test  cueswitch 1877  205  1  2239 
8: 32913  15  5  test taskswitch 2271  203  1  2239 
9: 30413  16  1 practice taskswitch 1377  203  1  1377 
10: 30413  16  2 practice taskswitch 1648  203  1  1377 
11: 30413  16  3 practice  cueswitch 1181  205  1  1377 
12: 30413  16  1  test  cueswitch 1045  205  1  1045 
13: 30413  16  2  test cuerepetition  969  203  0  1045 
14: 30413  16  3  test  cueswitch  857  203  1  1045 
15: 30413  16  4  test taskswitch 1038  205  1  1045 
16: 30413  16  5  test cuerepetition  836  203  0  1045 

Так вот лишь некоторые мысли, чтобы вы начали. Я предпринял эти усилия, потому что хотел показать вам, что большинство вещей становится очень легким, когда вы понимаете основы базы данных . Это должно быть мотивацией, чтобы пройти через руководства, которые вначале могут быть немного переборщиками. Но это стоит усилий, поверьте мне! Потому что я даже не упомянул лучшую часть: data.table также очень быстр. Так что удачи в анализе.

+0

Большое вам спасибо за быстрый учебник. Я думаю, что data.table и plyr - отличные варианты, и у меня возникает соблазн попробовать оба. Я начну читать :) – AlexR

3

Пакет plyr удобен для такого рода вещей (также data.table, но я не знаю его синтаксиса). Вот пример, чтобы начать работу:

my_function <- function(tmp){ 
    data.frame(n_trials = sum(tmp[ ,'trialn']), 
      n_trialslat = sum(tmp[tmp[,'latency'] <= 300 ,'trialn']), 
      mean_latency = mean(tmp[,'latency'])) 
} 
library(plyr) 
ddply(subset(d, blockcode == "test"), 'subject', my_function) 
+0

Я добавил некоторые мысли о 'data.table'. –

+0

Спасибо за демонстрацию и за предложение plyr и data.table. Это был трудный выбор, принимающий лучший ответ, поскольку они оба очень полезны. – AlexR

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