如何创建函数以从数据框返回指定的值

时间:2018-01-03 12:34:51

标签: r

我正在创建一个模型来分配对等位基因的适应性。我首先为人口创造了基因组(有效)

locus.info <- list(betalocus=c(A=0.8204,S=0.0512, C=0.1284))
create.genome <- function(locus.info)
{
num.loci <- length(locus.info)
gg <- vector(length=2*num.loci)
for (ll in 1:num.loci) {
alleles <- sample(names(locus.info[[ll]]), size=2, replace=TRUE, 
prob=locus.info[[ll]])
gg[c(ll, ll+num.loci)] <- alleles
}
return(gg)
} 
num.inds <- 30
pop <- data.frame(t(replicate(num.inds, create.genome (locus.info))), 
stringsAsFactors =FALSE)

pop
    X1 X2
1   A  A
2   A  A
3   A  A
4   A  A
5   A  A
6   C  A
7   A  A
8   A  A
9   A  A
10  A  A
11  A  A
12  A  A
13  A  S
14  A  C
15  A  A
16  A  A
17  A  A
18  A  A
19  A  C
20  A  A
21  A  C
22  C  A
23  A  A
24  A  A
25  C  C
26  A  A
27  A  A
28  A  S
29  A  A
30  A  A

然后我想创建一个函数,为名为pop的人口数据框中产生的每个基因型分配一个特定的适应度 - 我试过这个

ind_fit<-function(a,b)
{
 pop<-matrix(0,nrow=1,ncol=2)
 pop[1,1]<-a
 pop[1,2]<-b
 indfitness <- ifelse(pop[,1]=="A" & pop[,2]=="A", 0.861,
                ifelse(pop[,1]=="C" & pop[,2]=="C", 1,
                  ifelse(pop[,1]=="S" & pop[,2]=="S", 0.109,
                   ifelse(pop[,1]=="C" & pop[,2]=="A", 0.935,
                     ifelse(pop[,1]=="A" & pop[,2]=="C", 0.935,
                       ifelse(pop[,1]=="A" & pop[,2]=="S", 0.979,                                                     
                         ifelse(pop[,1]=="S" & pop[,2]=="A", 0.979, 0.498)
                 ))))))
 return(indfitness)
 }

然而我输入的每个值我总是得到0.498,尽管基本类型(字母)在pop数据框中是什么

 ind_fit(1,1) 
 0.498

如果在我的流行数据框中我有&#39; AA&#39;我得到0.861返回?

我希望得到第一排“AA&#39;返回0.861而不是0.498

2 个答案:

答案 0 :(得分:1)

如果你写的是这样的情况,你将总是有一个带有字母的两列数据框(假设你不想完全重新思考,比如使用tidyverse)。

ind_fit<-function(pop)
{

    indfitness <- ifelse(pop[,1]=="A" & pop[,2]=="A", 0.861,
            ifelse(pop[,1]=="C" & pop[,2]=="C", 1,
              ifelse(pop[,1]=="S" & pop[,2]=="S", 0.109,
               ifelse(pop[,1]=="C" & pop[,2]=="A", 0.935,
                 ifelse(pop[,1]=="A" & pop[,2]=="C", 0.935,
                   ifelse(pop[,1]=="A" & pop[,2]=="S", 0.979,                                                     
                     ifelse(pop[,1]=="S" & pop[,2]=="A", 0.979, 0.498)
             ))))))
      return(indfitness)
 }

就我个人而言,我宁愿使用比这个或dplyr解决方案更好的哈希,但那是r的美丽。或者只是在基地R。

pop <- data.frame(X1 = c("A", "A"), X2 = c("C", "S"))
ind_fit<-function(pop)
{

  pop$indfitness[pop$X1=="A" & pop$X2=="A"]<-0.861
  pop$indfitness[pop$X1=="C" & pop$X2=="C"] <- 1
  pop$indfitness[pop$X1=="S" & pop$X2=="S"] <-0.109
  pop$indfitness[pop$X1=="C" & pop$X2=="A"] <- 0.935
  pop$indfitness[pop$X1=="A" & pop$X2=="C"] <- 0.935
  pop$indfitness[pop$X1=="A" & pop$X2=="S"] <- 0.979                                                     
  pop$indfitness[pop$X1=="S" & pop$X2=="A"] <- 0.979

  pop  # or pop$indfitness depending on what you want.
}

答案 1 :(得分:0)

您可以在case_when中使用dplyr语句。如果我使用包含pop列和X1列的X2数据框,则以下代码应该执行您想要的操作。

library(dplyr)
popf = function(pop) {
    pop %>% mutate(
        result = case_when(
            X1=="A" & X2=="A" ~ 0.861,
            X1=="C" & X2=="C" ~ 1,
            X1=="S" & X2=="S" ~ 0.109,
            X1=="C" & X2=="A" ~ 0.935,
            X1=="A" & X2=="C" ~ 0.935,
            X1=="A" & X2=="S" ~ 0.979,
            X1=="S" & X2=="A" ~ 0.979,
            TRUE ~ 0.498)
        )
}
popf(pop)

编辑添加函数包装器。