У меня есть датафрейм в R, который выглядит примерно так:
library(tibble)
sample <- tribble(~subj, ~session,
"A", 1,
"A", 2,
"A", 3,
"B", 1,
"B", 2,
"C", 1,
"C", 2,
"C", 3,
"C", 4)
Как вы можете видеть из этого примера, есть несколько сеансов для каждого предмета, но не у всех предметов одинаковые количество сеансов. В моем реальном наборе данных 94 строки (5 предметов, от 15 до 20 различных сессий в каждой).
У меня есть другой скрипт, который берет мой основной набор данных (набор лингвистических c данных с подробным phoneti c функции для каждого предмета в каждом сеансе (почти 200 000 строк) и фильтры по предмету и сеансу для создания матрицы расстояний, показывающей евклидовы расстояния между различными словами. Я не могу воспроизвести его здесь по практическим соображениям, но создал пример сценария здесь:
library(tibble)
data <- tribble(~subj, ~session, ~Target, ~S1C1_target, # S1C1 = syllable 1, consonant 1
~S1C1_T.Sonorant, ~S1C1_T.Consonantal, # _T. = target consonant of S1C1
~S1C1_T.Voice, ~S1C1_T.Nasal, ~S1C1_T.Degree, # .Voice/.Nasal/etc are phonetic
# properties of the target word
"A", 1, "electricity", "i", 0, 0, 0, 0, 0,
"A", 1, "hectic", "h", 0.8, 0, 1, 0, 0,
"A", 1, "pillow", "p", -1, 1, -1, 0, 0,
"A", 2, "hello", "h", -0.5, 1, 0, -1, 0,
"A", 2, "cup", "k", 0.8, 0, 1, 0, 0,
"A", 2, "exam", "e", 0, 0, 0, 0, 0,
"B", 1, "wug", "w", 0.8, 0, 1, 0, 0,
"B", 1, "wug", "w", 0.8, 0, 1, 0, 0,
"B", 1, "hug", "h", 0.8, 0, 1, 0, 0,
"B", 2, "wug", "w", -0.5, 1, 0, -1, 0,
"B", 2, "well", "w", 0.8, 0, 1, 0, 0,
"B", 2, "what", "w", 0.8, 0, 1, 0, 0)
Я хочу начать с создания подмножества данных для каждого субъекта в каждом сеансе. Иногда у участника есть более одного токена одного и того же слова в Target
, поэтому я также создаю среднее значение для повторных итераций:
matrixA1 <- data %>% # name the data after the subj and session name/number
filter(subj == "A" & session == 1) %>%
dplyr::select(-subj, -session) %>% # leave only the numeric values + `Target`
group_by(Target) %>%
summarize_all(.funs = list(mean)) # Average across targets with more than one token
##### Calculate Euclidean distance between each phonetic property of each S1C1 target consonant
ones <- rep(1,nrow(matrixA1)) # count repeated rows
Son.mat.S1C1_T <- matrixA1$S1C1_T.Sonorant %*% t(ones) - ones %*% t(matrixA1$S1C1_T.Sonorant)
rownames(Son.mat.S1C1_T) <- matrixA1$Target
colnames(Son.mat.S1C1_T) <- matrixA1$Target
colnames(Son.mat.S1C1_T) <- paste(colnames(Son.mat.S1C1_T), "Son.S1C1_T", sep = "_")
Son.mat.S1C1_T <- Son.mat.S1C1_T^2
Con.mat.S1C1_T <- matrixA1$S1C1_T.Consonantal %*% t(ones) - ones %*% t(matrixA1$S1C1_T.Consonantal)
rownames(Con.mat.S1C1_T) <- matrixA1$Target
colnames(Con.mat.S1C1_T) <- matrixA1$Target
colnames(Con.mat.S1C1_T) <- paste(colnames(Con.mat.S1C1_T), "Con.S1C1_T", sep = "_")
Con.mat.S1C1_T <- Con.mat.S1C1_T^2
Voice.mat.S1C1_T <- matrixA1$S1C1_T.Voice %*% t(ones) - ones %*% t(matrixA1$S1C1_T.Voice)
rownames(Voice.mat.S1C1_T) <- matrixA1$Target
colnames(Voice.mat.S1C1_T) <- matrixA1$Target
colnames(Voice.mat.S1C1_T) <- paste(colnames(Voice.mat.S1C1_T), "Voice.S1C1_T", sep = "_")
Voice.mat.S1C1_T <- Voice.mat.S1C1_T^2
Nasal.mat.S1C1_T <- matrixA1$S1C1_T.Nasal %*% t(ones) - ones %*% t(matrixA1$S1C1_T.Nasal)
rownames(Nasal.mat.S1C1_T) <- matrixA1$Target
colnames(Nasal.mat.S1C1_T) <- matrixA1$Target
colnames(Nasal.mat.S1C1_T) <- paste(colnames(Nasal.mat.S1C1_T), "Nasal.S1C1_T", sep = "_")
S1C1.1A <- Son.mat.S1C1_T +
Con.mat.S1C1_T +
Voice.mat.S1C1_T +
Nasal.mat.S1C1_T
colnames(S1C1.1A) = gsub("_Son.S1C1_T", "", colnames(S1C1.1A))
Это создает матрицу, которая выглядит примерно так:
electricity hectic pillow
electricity 0.00 1.64 3.00
hectic 1.64 0.00 8.24
pillow 3.00 8.24 0.00
Как видите, этот код уже достаточно большой, а реальный код намного длиннее. Я знаю, что любой oop будет лучшим способом справиться с этим, но я не могу понять, как его запустить. Я хотел бы, чтобы это было так:
- Для каждой строки в
sample
создайте фрейм данных с subj
и session
в качестве идентификаторов в имени - Для каждого из этих фреймов данных запустите приведенный выше скрипт, начиная с
#####
, чтобы создать матрицу для каждого предмета и каждого сеанса, как показано выше.
Для этого, я думаю, лучше всего можно встроить скрипт в for-l oop и указать, что он должен запускаться для каждой строки в sample
.