Как вы можете зациклить эту функцию высшего порядка в R?
Этот вопрос относится к ответу, который я получил здесь с милой маленькой функцией от thelatemail. Фрейм данных, который я использую, не оптимален, но это то, что у меня есть, и я просто пытаюсь зациклить эту функцию по всем строкам.
Это мой дф
dput(SO_Example_v1)
structure(list(Type = structure(c(3L, 1L, 2L), .Label = c("Community",
"Contaminant", "Healthcare"), class = "factor"), hosp1_WoundAssocType = c(464L,
285L, 24L), hosp1_BloodAssocType = c(73L, 40L, 26L), hosp1_UrineAssocType = c(75L,
37L, 18L), hosp1_RespAssocType = c(137L, 77L, 2L), hosp1_CathAssocType = c(80L,
34L, 24L), hosp2_WoundAssocType = c(171L, 115L, 17L), hosp2_BloodAssocType = c(127L,
62L, 12L), hosp2_UrineAssocType = c(50L, 29L, 6L), hosp2_RespAssocType = c(135L,
142L, 6L), hosp2_CathAssocType = c(95L, 24L, 12L)), .Names = c("Type",
"hosp1_WoundAssocType", "hosp1_BloodAssocType", "hosp1_UrineAssocType",
"hosp1_RespAssocType", "hosp1_CathAssocType", "hosp2_WoundAssocType",
"hosp2_BloodAssocType", "hosp2_UrineAssocType", "hosp2_RespAssocType",
"hosp2_CathAssocType"), class = "data.frame", row.names = c(NA,
-3L))
####################
#what it looks like#
####################
require(dplyr)
df <- tbl_df(SO_Example_v1)
head(df)
Type hosp1_WoundAssocType hosp1_BloodAssocType hosp1_UrineAssocType
1 Healthcare 464 73 75
2 Community 285 40 37
3 Contaminant 24 26 18
Variables not shown: hosp1_RespAssocType (int), hosp1_CathAssocType (int), hosp2_WoundAssocType
(int), hosp2_BloodAssocType (int), hosp2_UrineAssocType (int), hosp2_RespAssocType (int),
hosp2_CathAssocType (int)
У меня есть функция, чтобы выполнить chisq.test
по всем категориям в df$Type
, В идеале функция должна переключиться на fisher.test()
если число ячеек <5, но это отдельная проблема (дополнительные очки брауни для человека, который придумывает, как это сделать).
Это функция, которую я использую, чтобы идти строка за строкой
func <- Map(
function(x,y) {
out <- cbind(x,y)
final <- rbind(out[1,],colSums(out[2:3,]))
chisq <- chisq.test(final,correct=FALSE)
chisq$p.value
},
SO_Example_v1[grepl("^hosp1",names(SO_Example_v1))],
SO_Example_v1[grepl("^hosp2",names(SO_Example_v1))]
)
func
Но в идеале я бы хотел, чтобы это было что-то вроде этого
for(i in 1:nrow(df)){func}
Но это не работает. Еще один прием заключается в том, что когда, например, берется второй ряд, final
звонок выглядит так
func <- Map(
function(x,y) {
out <- cbind(x,y)
final <- rbind(out[2,],colSums(out[c(1,3),]))
chisq <- chisq.test(final,correct=FALSE)
chisq$p.value
},
SO_Example_v1[grepl("^hosp1",names(SO_Example_v1))],
SO_Example_v1[grepl("^hosp2",names(SO_Example_v1))]
)
func
поэтому функция должна понимать, что число клеток out[x,]
должен быть исключен из colSums()
, это data.frame
только 3 строки, так что это легко, но я попытался применить эту функцию к отдельному data.frame, который у меня есть>200 строк, поэтому было бы неплохо иметь возможность как-то зацикливать это.
Любая помощь приветствуется.
ура
1 ответ
Вам не хватало двух вещей:
- Чтобы выбрать строку i и выбрать все, кроме этой строки, которую вы хотите использовать
u[i]
а такжеu[-i]
- Если элемент не такой длины, как другие, заданные для Map, он используется повторно, что является очень общим свойством языка. Затем вам просто нужно добавить в функцию аргумент, соответствующий строке, которую вы хотите противопоставить другим, и она будет переработана для всех элементов переданных векторов.
Следующее делает то, что вы просили
# the function doing the stats
FisherOrChisq <- function(x,y,lineComp) {
out <- cbind(x,y)
final <- rbind(out[lineComp,],colSums(out[-lineComp,]))
test <- chisq.test(final,correct=FALSE)
return(test$p.value)
}
# test of the stat function
FisherOrChisq(SO_Example_v1[grep("^hosp1",names(SO_Example_v1))[1]],
SO_Example_v1[grep("^hosp2",names(SO_Example_v1))[1]],2)
# making the loop
result <- c()
for(type in SO_Example_v1$Type){
line <- which(SO_Example_v1$Type==type)
res <- Map(FisherOrChisq,
SO_Example_v1[grepl("^hosp1",names(SO_Example_v1))],
SO_Example_v1[grepl("^hosp2",names(SO_Example_v1))],
line
)
result <- rbind(result,res)
}
colnames(result) <- gsub("^hosp[0-9]+","",colnames(result))
rownames(result) <- SO_Example_v1$Type
Тем не менее, то, что вы делаете, это очень тяжелое многократное тестирование. Я был бы очень осторожен с использованием соответствующих значений p, вам нужно, по крайней мере, использовать множественную коррекцию тестирования, такую как предложенная здесь.