Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R中嵌套for循环的更快替代方法_R_Loops - Fatal编程技术网

R中嵌套for循环的更快替代方法

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", "

下面是一个场景:我有一个样本,其中的受试者被分为三组。接下来,将每组受试者分组,形成由每组受试者组成的几个“三胞胎”。我想计算来自给定组(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", "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