R 在循环中同时使用子集和整个数据帧

R 在循环中同时使用子集和整个数据帧,r,if-statement,apply,R,If Statement,Apply,我正在尝试编写一个函数,该函数在数据帧的行上循环,并使用有关其他行的信息来确定每个循环的输出 考虑以下数据框,该数据框用于表示具有经度坐标、纬度坐标和值的人,以表示他们是否生病: game.mat<-as.data.frame(matrix(0, nrow = 100, ncol = 3)) colnames(game.mat)<-c("PosX","PosY","Sick") game.mat[,"PosX"]<-sample(x = c(1:100), 100, repla

我正在尝试编写一个函数,该函数在数据帧的行上循环,并使用有关其他行的信息来确定每个循环的输出

考虑以下数据框,该数据框用于表示具有经度坐标、纬度坐标和值的人,以表示他们是否生病:

game.mat<-as.data.frame(matrix(0, nrow = 100, ncol = 3))
colnames(game.mat)<-c("PosX","PosY","Sick")
game.mat[,"PosX"]<-sample(x = c(1:100), 100, replace = TRUE)
game.mat[,"PosY"]<-sample(x = c(1:100), 100, replace = TRUE)
game.mat[,"Sick"]<-sample((c(rep(0,8),rep(1,2))),100,replace=TRUE)
一些少数人在基线检查时会生病。我的功能是要感染与病人相邻的x-y坐标的人,所以任何与病人相邻的人。我考虑在ifelse语句中嵌入这样的函数:

 search_sick<-function(d,corx,cory){
   d2<-d[d$PosX<corx+2&d$PosX>corx-2&d$PosY<cory+2&d$PosY>cory-2,]
   if(sum(d2$Sick>0)){
    d$Sick<-1
   } else{
    d$Sick<-0
   }
  } 
但它会让每个人都生病,可能是因为如果有人在病人旁边,它会给每个人一个值1。我还考虑使用apply函数。但根据我对apply的理解,它一次只能在一行中运行,因此无法检索关于其他行是否具有相邻坐标值的信息

我希望这是有道理的。乐意提供更多信息

下面是一个使用apply的示例

我们将修改您的函数,使其具有灵活的搜索半径r,并返回新感染个体的索引

search_sick<-function(d, corx, cory, r){
  indx<-which(d$PosX<corx+r & d$PosX>corx-r & d$PosY<cory+r & d$PosY>cory-r)
}

contagious<-game.mat[game.mat$Sick==1,]

infected<-apply(contagious, 1, function(x) {
  search_sick(game.mat, x[1], x[2], r=10)
})

game.mat$T1<-game.mat$Sick

game.mat$T1[unique(unlist(infected))]<-1

#circle points which have become sick
points(PosY~PosX, data=game.mat[game.mat$Sick==0 & game.mat$T1==1,], col="red", cex=2) 

我不确定我是否理解你试图使用的逻辑。corx和cory是指用户输入函数的空间中的单个点吗?还是要同时搜索所有受感染的个人?还是别的什么?我已经给出了下面第一个病例的解决方案,但如果这不是你想要的,请告诉我。我想同时搜索所有感染者。这就是我遇到的问题。谢谢!这是一个很好和优雅的方法。尽管在理想情况下,我能够轻松地循环数据帧的行,向函数提供所有患病个体的坐标,并在不断更新数据帧的同时独立地运行这些坐标的函数。这一点尤其重要,因为函数嵌入到for循环中,所以我需要自动输入坐标,而不是自己输入坐标。感谢您的澄清,我已经相应地更新了我的答案。
search_sick<-function(d, corx, cory, r){
  indx<-which(d$PosX<corx+r & d$PosX>corx-r & d$PosY<cory+r & d$PosY>cory-r)
}

contagious<-game.mat[game.mat$Sick==1,]

infected<-apply(contagious, 1, function(x) {
  search_sick(game.mat, x[1], x[2], r=10)
})

game.mat$T1<-game.mat$Sick

game.mat$T1[unique(unlist(infected))]<-1

#circle points which have become sick
points(PosY~PosX, data=game.mat[game.mat$Sick==0 & game.mat$T1==1,], col="red", cex=2)