微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在R中的嵌套函数中合并函数的输出

如何解决在R中的嵌套函数中合并函数的输出

我有2个函数,每个函数提供不同的输出,我试图创建一个合并这些函数的2个输出的新函数,但是不断收到错误消息,指出未找到对象,我知道一旦出局在我的任何函数中(在常规函数内部),main函数都无法识别这些对象。我不知道如何在主要功能的全局环境中识别这些输出。这是代码

#############################################################################
#############################################################################
# 1. datasets 
IDr= c(seq(1,5))
BTR=c("A","B","AB","O","O")
data_R=data.frame(IDr,BTR,A=c(0,1,rep(0,3)),B=c(0,3),1),C=c(0,rep(1,0),D=c(0,4)),E=c(1,stringsAsFactors=FALSE)

 data_R
  IDr BTR A B C D E
1   1   A 0 0 0 0 1
2   2   B 1 0 1 1 1
3   3  AB 0 0 1 1 0
4   4   O 0 0 1 1 1
5   5   O 0 1 0 1 0


IDd= c(seq(1,8))
BTD= c("A","O")
fg= c(rep(0.0025,each=2),rep(0.00125,rep(0.0011,rep(0.0015,each=2))
data_D=data.frame(IDd,BTD,A=c(rep(0,5),B=c(rep(0,6),C=c(rep(1,7),D=rep(1,8),E=c(rep(0,2),fg,stringsAsFactors=FALSE)

  data_D
  IDd BTD A B C D E      fg
1   1   A 0 0 1 1 0 0.00250
2   2   B 0 0 1 1 0 0.00250
3   3  AB 0 0 1 1 0 0.00125
4   4   O 0 0 1 1 0 0.00125
5   5  AB 0 0 1 1 0 0.00110
6   6  AB 1 0 1 1 1 0.00110
7   7   O 1 1 1 1 1 0.00150
8   8   O 1 1 0 1 0 0.00150
############################################################################
############################################################################
# fist function
# calulate the frequency of repeated set (A:E) using fg 
freq<- function(df,Vars,col.interest){
  col.interest=as.data.frame(col.interest)
  resultat1= df  %>% 
    group_by(across(all_of(Vars))) %>%
    dplyr::summarise(count = n(),frequency.epi = sum(fg),.groups = 'drop')
  res=merge(resultat1,col.interest,all=TRUE)
  res_final=cbind(df[1:2],res)
  return(res_final)
  
}

dfreq= freq(data_D,colnames(data_D)[3:7],data_D[3:7])
dfreq
  IDd BTD A B C D E count frequency.epi
1   1   A 0 0 1 1 0     5        0.0086
2   2   B 0 0 1 1 0     5        0.0086
3   3  AB 0 0 1 1 0     5        0.0086
4   4   O 0 0 1 1 0     5        0.0086
5   5  AB 0 0 1 1 0     5        0.0086
6   6  AB 1 0 1 1 1     1        0.0011
7   7   O 1 1 0 1 0     1        0.0015
8   8   O 1 1 1 1 1     1        0.0015
###############################################################
# the second function that was corrected by @MrFlic 
 mis.test = function(D,R,threshold) { 
  D = as.data.frame(D)
  R = as.data.frame(R)
  mismatch.i = function(i) {
    dif = purrr::map2_df(D[-1],R[i,-1],`-`)
    dif[dif<0] = 0
    dif$mismatch=rowSums(dif)
    dif = cbind(ID = D[1],IDr=R[i,1],dif)
    dif = dif[which(dif$mismatch <= threshold),]
    return(list=dif[c(1,2,ncol(dif))])
  }
  
  diff.mat = do.call(rbind,lapply(1:nrow(R),function(x) mismatch.i(x)))
  diff.mat = as.data.frame(diff.mat)
  return(diff.mat)
}
# if i want mis.test for 1 person 
mis_one=mis.test(data_D[,c(1,3:7)],data_R[1,2)
mis_one
  IDd IDr mismatch
1   1   1        2
2   2   1        2
3   3   1        2
4   4   1        2
5   5   1        2

# what i want to do in the main function is this step (for example using these exact outputs)
merge(mis_one,dfreq,by="IDd") # this was executed outside to show the expected output
# this is the output expected that i want if i run the main function 

  IDd IDr mismatch BTD A B C D E count frequency.epi
1   1   1        2   A 0 0 1 1 0     5        0.0086
2   2   1        2   B 0 0 1 1 0     5        0.0086
3   3   1        2  AB 0 0 1 1 0     5        0.0086
4   4   1        2   O 0 0 1 1 0     5        0.0086
5   5   1        2  AB 0 0 1 1 0     5        0.0086

这是主要功能,有很多错误

test.merge=function(D,DF,threshold,col.interest){
  R=as.data.frame(R)
  D=as.data.frame(D)
  DF=as.data.frame(DF)
  col.interest=as.data.frame(col.interest)
  # remark1: Here i kNow i repeated the same arguments because i did not kNow what to set in order to do the calculation
  freq.epi<- function( Vars,col.interest){
    resultat1= DF  %>% 
      group_by(across(all_of(Vars))) %>%
      dplyr::summarise(count = n(),.groups = 'drop')
    res=merge(resultat1,all=TRUE)
    res_final=cbind(DF[1:2],res)
    return(res_final)
    
  }
  # same as remark1 for the arguments
  mis.test = function(D,threshold) { 
    D = as.data.frame(D)
    R = as.data.frame(R)
    mismatch.i = function(i) {
      dif = purrr::map2_df(D[-1],`-`)
      dif[dif<0] = 0
      dif$mismatch=rowSums(dif)
      dif = cbind(ID = D[1],dif)
      dif = dif[which(dif$mismatch <= threshold),]
      return(list=dif[c(1,ncol(dif))])
    }
    diff.mat = do.call(rbind,function(x) mismatch.i(x)))
    diff.mat = as.data.frame(diff.mat)
    return(diff.mat)
  }
  # i dont kNow how to make diff.mat and res_final visible for test.merge
  # i am trying to merge the two outputs res_final and diff.mat by the IDd
  tab=merge(diff.mat,res_final,by="IDd")
  return(tab)
  
}

test.merge(data_D[,data_D,data_D[3:7])
# Error in merge(diff.mat,by = "IDd") : 
# object 'diff.mat' not found

我不知道在主函数中是否还有其他方法可以使用函数输出。预先感谢您的帮助

解决方法

为什么要将所有功能混合在一起?我建议将它们分开并写test.merge以仅合并2个输出中的数据。

freq<- function(df,Vars,col.interest){
  col.interest=as.data.frame(col.interest)
  resultat1= df  %>% 
    group_by(across(all_of(Vars))) %>%
    dplyr::summarise(count = n(),frequency.epi = sum(fg),.groups = 'drop')
  res=merge(resultat1,col.interest,all=TRUE)
  res_final=cbind(df[1:2],res)
  return(res_final)
  
}

mis.test = function(D,R,threshold) { 
  D = as.data.frame(D)
  R = as.data.frame(R)
  mismatch.i = function(i) {
    dif = purrr::map2_df(D[-1],R[i,-1],`-`)
    dif[dif<0] = 0
    dif$mismatch=rowSums(dif)
    dif = cbind(ID = D[1],IDr=R[i,1],dif)
    dif = dif[which(dif$mismatch <= threshold),]
    return(list=dif[c(1,2,ncol(dif))])
  }
  
  diff.mat = do.call(rbind,lapply(1:nrow(R),function(x) mismatch.i(x)))
  diff.mat = as.data.frame(diff.mat)
  return(diff.mat)
}

test.merge = function(x,y) {
  merge(x,y,by="IDd")
}
test.merge(mis.test(data_D[,c(1,3:7)],data_R[1,2),freq(data_D,colnames(data_D)[3:7],data_D[3:7]))

#  IDd IDr mismatch BTD A B C D E count frequency.epi
#1   1   1        2   A 0 0 1 1 0     5        0.0086
#2   2   1        2   B 0 0 1 1 0     5        0.0086
#3   3   1        2  AB 0 0 1 1 0     5        0.0086
#4   4   1        2   O 0 0 1 1 0     5        0.0086
#5   5   1        2  AB 0 0 1 1 0     5        0.0086

这是您原始代码的修复程序。

test.merge=function(D,threshold,DF,col.interest){
  R=as.data.frame(R)
  D=as.data.frame(D)
  DF=as.data.frame(DF)
  col.interest=as.data.frame(col.interest)
 
  freq.epi<- function(DF,col.interest){
    resultat1= DF  %>% 
      group_by(across(all_of(Vars))) %>%
      dplyr::summarise(count = n(),.groups = 'drop')
    res=merge(resultat1,all=TRUE)
    res_final=cbind(DF[1:2],res)
    return(res_final)
    
  }
  # same as remark1 for the arguments
  mis.test = function(D,threshold) { 
    D = as.data.frame(D)
    R = as.data.frame(R)
    mismatch.i = function(i) {
      dif = purrr::map2_df(D[-1],`-`)
      dif[dif<0] = 0
      dif$mismatch=rowSums(dif)
      dif = cbind(ID = D[1],dif)
      dif = dif[which(dif$mismatch <= threshold),]
      return(list=dif[c(1,ncol(dif))])
    }
    diff.mat = do.call(rbind,function(x) mismatch.i(x)))
    diff.mat = as.data.frame(diff.mat)
    return(diff.mat)
  }
  
  tab=merge(mis.test(D,threshold),freq.epi(DF,col.interest),by="IDd")
  return(tab)
  
}

test.merge(data_D[,data_D,data_D[3:7])

我确信可以以更好的方式对其进行优化和编写(如第1部分中所述),但是由于我不了解此处的大图,因此将其留给OP。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。