R中嵌套for循环的更快替代方法
下面是一个场景:我有一个样本,其中的受试者被分为三组。接下来,将每组受试者分组,形成由每组受试者组成的几个“三胞胎”。我想计算来自给定组(1、2或3)的受试者与不同原始组的受试者I分组的次数 下面是一个简单的代码示例:R中嵌套for循环的更快替代方法,r,loops,R,Loops,下面是一个场景:我有一个样本,其中的受试者被分为三组。接下来,将每组受试者分组,形成由每组受试者组成的几个“三胞胎”。我想计算来自给定组(1、2或3)的受试者与不同原始组的受试者I分组的次数 下面是一个简单的代码示例: data <- cbind(c(1:9), c(rep("Group 1", 3), rep("Group 2", 3), rep("Group 3", 3))) data <- data.frame(data) names(data) <- c("ID", "
data <- cbind(c(1:9), c(rep("Group 1", 3), rep("Group 2", 3), rep("Group 3", 3)))
data <- data.frame(data)
names(data) <- c("ID", "Group")
groups.of.3 <- data.frame(rbind(c(1,4,7),c(2,4,7),c(2,5,7),c(3,6,8),c(3,6,9)))
N <- nrow(data)
n1 <- nrow(data[data$Group == "Group 1", ])
n2 <- nrow(data[data$Group == "Group 2", ])
n3 <- nrow(data[data$Group == "Group 3", ])
# Check the number of times a subject from a group is grouped with a subject i
# from another group
M1 <- matrix(0, nrow = N, ncol = n1)
M2 <- matrix(0, nrow = N, ncol = n2)
M3 <- matrix(0, nrow = N, ncol = n3)
for (i in 1:N){
if (data$Group[i] != "Group 1"){
for (j in 1:n1){
M1[i,j] <- nrow(groups.of.3[groups.of.3[,1] == j &
(groups.of.3[,2] == i |
groups.of.3[,3] == i), ])
}
}
if (data$Group[i] != "Group 2"){
for (j in 1:n2){
M2[i,j] <- nrow(groups.of.3[groups.of.3[,2] == (n1 + j) &
(groups.of.3[,1] == i |
groups.of.3[,3] == i), ])
}
}
if (data$Group[i] != "Group 3"){
for (j in 1:n3){
M3[i,j] <- nrow(groups.of.3[groups.of.3[,3] == (n1 + n2 + j) &
(groups.of.3[,1] == i |
groups.of.3[,2] == i), ])
}
}
}
因此,3列代表第1组的三名受试者,行代表所有受试者-条目是第1组的每名受试者与任何其他受试者分组的次数(例如,根据组3,受试者3与受试者6出现两次,受试者1与受试者7出现一次)
谢谢你的帮助 像这样的
library(tidyr)
library(dplyr)
data <- data %>%
mutate(ID = as.numeric(levels(ID))[ID])
tmp <- groups.of.3 %>%
add_rownames() %>%
gather("X", "Person", -rowname) %>%
inner_join(data, by = c("Person" = "ID"))
tmp %>%
inner_join(tmp, by = c("rowname")) %>%
filter(Group.x != Group.y) %>%
group_by(Person.x, Group.x, Group.y) %>%
summarise(N = n()) %>%
spread(key = Group.y, value = N, fill = 0)
Person.x Group.x Group 1 Group 2 Group 3
(dbl) (fctr) (dbl) (dbl) (dbl)
1 1 Group 1 0 1 1
2 2 Group 1 0 2 2
3 3 Group 1 0 2 2
4 4 Group 2 2 0 2
5 5 Group 2 1 0 1
6 6 Group 2 2 0 2
7 7 Group 3 3 3 0
8 8 Group 3 1 1 0
9 9 Group 3 1 1 0
library(tidyr)
图书馆(dplyr)
数据%
变异(ID=as.numeric(levels(ID))[ID])
tmp%
添加_rownames()%>%
聚集(“X”、“人”、-rowname)%>%
内部联接(数据,由=c(“人员”=“ID”))
tmp%>%
内部联接(tmp,by=c(“rowname”))%>%
过滤器(组x!=组y)%>%
组别(个人x、组别x、组别y)%>%
总结(N=N())%>%
排列(键=组y,值=N,填充=0)
个人x组x组1组2组3
(dbl)(fctr)(dbl)(dbl)(dbl)
1组1 0 1 1
2组1 0 2 2
3组1 0 2 2
4第2组2 0 2
5组2 1 0 1
6第2组2 0 2
7组3 3 0
8 8组3 1 0
9组3 1 0
For循环本身并不慢:
# coerce the fields in groups.of.3 to factor
for(i in 1:3)
groups.of.3[,i] <- as.factor(groups.of.3[,i],levels =data$ID)
M <- matrix(0, N, N)
out <- NULL
for(i in 1:(3-1))
for(j in (i+1):3)
M <- M + table(groups.of.3[,i],groups.of.3[,j])
M1 <- M[,as.integer(data$Group)==1]
M2 <- M[,as.integer(data$Group)==2]
M3 <- M[,as.integer(data$Group)==3]
#强制将.3组中的字段设置为factor
(我在1:3中)
3组[,i]我将回答我自己的问题,对蒂埃里的答案稍加修改:
图书馆(tidyr)
图书馆(dplyr)
谢谢你的回复!这很好,但我认为我更关心的是个别受试者的分组,而不是整个组。我在原来的问题上加了一部分来帮助澄清问题。例如,根据这一点,受试者2与第2组中的任何受试者出现在一个组中两次,但我想看看受试者2与单个受试者分组的次数。
# coerce the fields in groups.of.3 to factor
for(i in 1:3)
groups.of.3[,i] <- as.factor(groups.of.3[,i],levels =data$ID)
M <- matrix(0, N, N)
out <- NULL
for(i in 1:(3-1))
for(j in (i+1):3)
M <- M + table(groups.of.3[,i],groups.of.3[,j])
M1 <- M[,as.integer(data$Group)==1]
M2 <- M[,as.integer(data$Group)==2]
M3 <- M[,as.integer(data$Group)==3]
data <- data %>%
mutate(ID = as.numeric(levels(ID))[ID])
tmp <- groups.of.3 %>%
add_rownames() %>%
gather("X", "Person", -rowname) %>%
inner_join(data, by = c("Person" = "ID"))
tmp %>%
inner_join(tmp, by = c("rowname")) %>%
filter(Group.x != Group.y) %>%
group_by(Person.x, Group.x, Person.y) %>%
summarise(N = n()) %>%
spread(key = Person.y, value = N, fill = 0)
Source: local data frame [9 x 11]
Person.x Group.x 1 2 3 4 5 6 7 8 9
(dbl) (fctr) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl)
1 1 Group 1 0 0 0 1 0 0 1 0 0
2 2 Group 1 0 0 0 1 1 0 2 0 0
3 3 Group 1 0 0 0 0 0 2 0 1 1
4 4 Group 2 1 1 0 0 0 0 2 0 0
5 5 Group 2 0 1 0 0 0 0 1 0 0
6 6 Group 2 0 0 2 0 0 0 0 1 1
7 7 Group 3 1 2 0 2 1 0 0 0 0
8 8 Group 3 0 0 1 0 0 1 0 0 0
9 9 Group 3 0 0 1 0 0 1 0 0 0