分类: R语言

  • R语言edit函数,调用可视化编辑器编辑数据

    这个函数在Linux和windows下都可用。

    a = data.frame(1:9)
    a <- edit(a)
    

  • R语言编写函数

    R语言的一大特色是可以自己编写函数。基本格式是把function赋予一个变量,例子如下:

    theData <- function(type="all"){
      switch(type,
             all=format(Sys.time(),"%Y %m %d %A"),
             part=format(Sys.time(),"%y-%m-%d"),
             cat("Please retype.")
      )
      
    }
    
    theData()
    theData("all")
    theData("part")
    

  • R语言的switch函数

    `switch`函数是R语言中效率很高的函数。语法为:

    switch(expr,...)
    

    expr是可能出现的值。例如

    aName <- sample(c("张三","李四","王五"),1)  # 抽取一个数字
    print(switch(aName,
    "张三"="first",
    "李四"="second",
    "王五"="third"))
    

  • R语言的merge函数

    两个数据集横向合并,又有相同的编号,可用merge()。

    data_merge <- merge(dataframe1,dataframe2,by="id")
    data_merge <- merge(dataframe1,dataframe2,by=c("id","room"))
    

  • R语言doMC包的安装

    doMC 包是 R 语言中的一个包,用于并行计算。它是foreach包的一个后端,允许用户通过多核处理器上的多线程来加速计算。doMC包实际上是multicore包的一个接口,后者是在Unix-like系统上进行并行计算的工具。使用doMC可以非常方便地在 R 中执行并行循环,提高数据分析和模型训练的效率。

    直接使用install.packages("doMC")安装时,会提示R版本不可用。

    需要采用下面的命令安装:

    install.packages("doMC", repos="http://R-Forge.R-project.org")
    
  • 第七章 R语言中的列表

    列表是一个能组织值、向量、数据框、矩阵等的容器,可以把各种变量按照顺序组织在一起。

    还是以表4-1为例,我们知道,计算只能在数值上,那么,实际上数据框是不适合直接计算的。我们把这个数据框改成列表。

    数据表4-1

    姓名性别英语成绩评定
    张三男95优秀
    李四女84良好
    王五男61合格
    name <- c("张三","李四","王五")
    gender <- c("男","女","男")
    English_score <- c(95,84,61)
    English_grade <- c("优秀","良好","合格")
    # 创建列表
    English_class <- list(name,gender,English_score,English_grade)
    # 显示列表内容
    English_class
    

    结果如下:

    > English_class
    [[1]]
    [1] "张三" "李四" "王五"
    
    [[2]]
    [1] "男" "女" "男"
    
    [[3]]
    [1] 95 84 61
    
    [[4]]
    [1] "优秀" "良好" "合格"

    像其他数据组织形式一样,列表也能命名。

    English_class <- list("姓名" = name, "性别" = gender, "英语成绩" = English_score, "英语评级" = English_grade)
    English_class
    

    结果如下:

    $姓名
    [1] "张三" "李四" "王五"
    
    $性别
    [1] "男" "女" "男"
    
    $英语成绩
    [1] 95 84 61
    
    $英语评级
    [1] "优秀" "良好" "合格"

    数据的提取:

    # 提取列表中的第一个元素,以列表形式展现
    English_class[1]
    
    # 提取列表中的第一个元素,以非列表形式展现,如向量、矩阵
    English_class[[1]]
    
    # 提取列表中第一个元素的第一个元素
    English_class[[1]][1]
    unlist(English_class[1])[1]
    
    # 已经命名的列表,可以用$符号提取元素,也可以直接用名称提取
    English_class["姓名"]
    English_class[["姓名"]]
    English_class$姓名
    English_class$姓名[1]
    

    结果如下:

    > # 提取列表中的第一个元素,以列表形式展现
    > English_class[1]
    $姓名
    [1] "张三" "李四" "王五"
    
    > 
    > # 提取列表中的第一个元素,以非列表形式展现,如向量、矩阵
    > English_class[[1]]
    [1] "张三" "李四" "王五"
    > 
    > # 提取列表中第一个元素的第一个元素
    > English_class[[1]][1]
    [1] "张三"
    > unlist(English_class[1])[1]
     姓名1 
    "张三" 
    > 
    > # 已经命名的列表,可以用$符号提取元素,也可以直接用名称提取
    > English_class["姓名"]
    $姓名
    [1] "张三" "李四" "王五"
    
    > English_class[["姓名"]]
    [1] "张三" "李四" "王五"
    > English_class$姓名
    [1] "张三" "李四" "王五"
    > English_class$姓名[1]
    [1] "张三"

    列表是有长度的,列表中元素的个数即为列表的长度,列表中某个元素中子元素的个数,为该子元素的长度。

    # 列表的长度
    length(English_class)
    # 列表中,子元素"姓名"的长度
    length(English_class$姓名)
    

    结果如下:

    > length(English_class)
    [1] 4
    > length(English_class$姓名)
    [1] 3

    我们可以向列表中添加内容,也就是元素。比如我们要加入数学和语文成绩。

    # 向列表中添加元素
    English_class[[length(English_class) + 1]] <- data.frame("数学成绩" = c(99, 88, 77), "语文成绩" = c(66, 55, 44))
    

    结果如下:

    > English_class
    $姓名
    [1] "张三" "李四" "王五"
    
    $性别
    [1] "男" "女" "男"
    
    $英语成绩
    [1] 95 84 61
    
    $英语评级
    [1] "优秀" "良好" "合格"
    
    [[5]]
      数学成绩 语文成绩
    1       99       66
    2       88       55
    3       77       44

    删除列表中的元素也是非常简单的,类似于向量的操作。

    # 删除元素
    (English_class[-2])   # 删除性别
    (English_class[[3]] <- NULL)   # 删除英语成绩
    English_class
    

    结果如下:

    > (English_class[-2])
    $姓名
    [1] "张三" "李四" "王五"
    
    $英语成绩
    [1] 95 84 61
    
    $英语评级
    [1] "优秀" "良好" "合格"
    
    [[4]]
      数学成绩 语文成绩
    1       99       66
    2       88       55
    3       77       44
    
    > (English_class[[3]] <- NULL)
    NULL
    > English_class
    $姓名
    [1] "张三" "李四" "王五"
    
    $性别
    [1] "男" "女" "男"
    
    $英语评级
    [1] "优秀" "良好" "合格"
    
    [[4]]
      数学成绩 语文成绩
    1       99       66
    2       88       55
    3       77       44

    列表是可以叠加的,把一个列表和另一个列表相连。我们把数学成绩和语文成绩从这个列表中删除,然后放在另一个列表内。

    (English_class[-4])
    other_score <- list("数学成绩" = c(99, 88, 77), "语文成绩" = c(66, 55, 44))
    list_in_list <- list(English_class,other_score)   # list_in_list <- append(English_class,other_score)两者有区别
    list_in_list
    

    结果如下:

    > (English_class[-4])
    $姓名
    [1] "张三" "李四" "王五"
    
    $性别
    [1] "男" "女" "男"
    
    $英语评级
    [1] "优秀" "良好" "合格"
    
    > other_score <- list("数学成绩" = c(99, 88, 77), "语文成绩" = c(66, 55, 44))
    > other_score
    $数学成绩
    [1] 99 88 77
    
    $语文成绩
    [1] 66 55 44
    
    > list_in_list <- list(English_class,other_score)
    > list_in_list
    [[1]]
    [[1]]$姓名
    [1] "张三" "李四" "王五"
    
    [[1]]$性别
    [1] "男" "女" "男"
    
    [[1]]$英语评级
    [1] "优秀" "良好" "合格"
    
    [[2]]
    [[2]]$数学成绩
    [1] 99 88 77
    
    [[2]]$语文成绩
    [1] 66 55 44

    类似的,查看列表的元素,可以用下面的代码。

    list_in_list[[1]]
    list_in_list[[2]]
    list_in_list[[1]]$姓名
    

    结果如下:

    > list_in_list[[1]]
    $姓名
    [1] "张三" "李四" "王五"
    
    $性别
    [1] "男" "女" "男"
    
    $英语评级
    [1] "优秀" "良好" "合格"
    
    > list_in_list[[2]]
    $数学成绩
    [1] 99 88 77
    
    $语文成绩
    [1] 66 55 44
    
    > list_in_list[[1]]$性别
    [1] "男" "女" "男"

  • 从参考基因组选取特定位置的碱基

    R代码如下

    #BiocManager::install('seqinr')   # 如果没安装过这包,先安装
    library(seqinr)
    library(stringr)
    fasta <- read.fasta(file = "C:\\Users\\zhang\\Desktop\\Zea_mays.AGPv4.dna.chromosome.1.fa",
        as.string = TRUE,
        forceDNAtolower = FALSE)   # 修改上面的路径,fasta格式文件
    class(fasta)
    
    a1 <- fasta[[2]][1]   # 这里的[1]不用改,[[2]]表示排在第二的染色体,玉米中是2号染色体
    str(a1)
    a1 <- strsplit(a1,"")
    str(a1)
    b <- read.table("clipboard",header=F)   # 从excel复制需要的染色体位置信息
    # b <- c(1,2,3,4,5)
    k <- data.frame(1:nrow(b))
    for (i in 1:nrow(b)){
        txt <- paste0("k[",i,",1] <- a1[[1]][as.numeric(b[",i,",1])]")
        eval(parse(text=txt))
    }
    
    write.table(k,"C:\\Users\\zhang\\Desktop\\123.txt",row.names=F,col.names=F,sep="\t",quote=F)
    
    

    Excel染色体位置信息如下,注意,这里没有包含染色体信息,需要每个染色体单独做。

    82048
    82052
    82071
    82079
    82089
    82097
    82100
    82104
    82107
    82136
    82148
    82185
    114009
    114027
    114043
    114092
    114103
    114168
  • Visual Studio Code+R

    Visual Studio Code是微软开发的开源、跨平台代码编辑器,号称宇宙最强!使用该编辑器直接编辑和运行R程序比使用RStudio占用资源更低,稳定性也好一些。

    R语言的下载

    进入R语言的官方网站,根据自己的所在地选择最适合的镜像站下载R(https://www.r-project.org/)。

    我选择的是兰州大学开源学会镜像(https://mirror.lzu.edu.cn/CRAN/),根据动画操作下载,版本号可能会有不同。

    如果电脑中已经安装了其他版本的R,建议先卸载,然后再安装。

    R语言的安装

    安装时,安装目录建议去掉横线,有些程序不识别目录中的短横线,容易造成错误。

    其他保持默认即可。

    下载VSCode和安装

    进入Visual Studio Code官网(https://code.visualstudio.com/),下载适合的版本,我这里以Windows 11 64 bit为例。安装保持默认即可。

    VSCode插件安装

    运行VSCode,按快捷键Ctrl+Shift+X调出扩展商店,在搜索栏输入“R”,安装R拓展。

    R语言安装languageserver包

    打开R,输入下列代码安装languageserver包,回车运行。

    install.packages("languageserver")
    

    在VSCode里运行R代码

    在VSCode中,选择菜单栏的文件→打开文件夹,选择一个经常编辑代码的文件夹。并信任该文件夹。

    按Ctrl+N新建一个文件,语言选择R。

    在第一行输入任意R代码,按Ctrl+Enter运行,查看结果。若能看到运行结果,则环境搭建完毕。

    getwd()
    
  • sommer包的GbyE分析

    sommer包可以做单环境模型、主效应模型、对角线模型(DG)、复合对称模型(CS)、复合对称+对角线模型(CS+DG)、非结构化模型(US)、随机回归模型(RR)和协方差结构G×E。当然,还可以有其他自己的组合。

    library(sommer)
    data(DT_example)
    DT <- DT_example  # 41个土豆材料,1个地点,3个年份=3个环境
    A <- A_example   # 系谱矩阵
    # 1. 单地点
    # BLUP
    ansSingle <- mmer(Yield~1,
                      random= ~ vs(Name, Gu=A),
                      rcov= ~ units,
                      data=DT, verbose = FALSE)
    summary(ansSingle)
    
    # 2. 主效应,假设没有基因型与环境互作
    # 环境作为固定效应+BLUP
    ansMain <- mmer(Yield~Env,
                    random= ~ vs(Name, Gu=A),
                    rcov= ~ units,
                    data=DT, verbose = FALSE)
    summary(ansMain)
    
    # 3. 对角线模型
    # 假设存在基因型与环境互作
    # 假设每个环境基因型的方差不同
    # 每个环境单独拟合基因型效应
    # 缺点:没有环境间的协方差(每个环境为不同个体)
    # 环境作为固定效应+单环境的BLUP(环境的对角线矩阵)
    ansDG <- mmer(Yield~Env,
                  random= ~ vs(ds(Env),Name, Gu=A),
                  rcov= ~ units,
                  data=DT, verbose = FALSE)
    summary(ansDG)
    
    # 4. 复合对称模型
    # 假设存在基因型与环境互作
    # 主要的基因型方差协方差分量跨所有环境
    # 假设主要的基因型效应被跨环境效应影响
    # 缺点:各环境之间有相同的方差-协方差
    # 环境作为固定效应+BLUP+GEI
    E <- diag(length(unique(DT$Env)))   # 环境的对角线矩阵
    rownames(E) <- colnames(E) <- unique(DT$Env)   #  添加环境名称
    # 克罗内克乘积,矩阵1的每一项×矩阵2的每一项
    # 若矩阵1是m×n,矩阵2是p×q,则克罗内克乘积是mp×nq的方形矩阵
    # make.dimnames表示添加行名列名
    EA <- kronecker(E,A, make.dimnames = TRUE)
    ansCS <- mmer(Yield~Env,
                  random= ~ vs(Name, Gu=A) + vs(Env:Name, Gu=EA),
                  rcov= ~ units,
                  data=DT, verbose = FALSE)
    summary(ansCS)
    
    # 5. 复合对称+对角线模型
    # 假设存在基因型与环境互作
    # 假设每个环境都有不同的基因型与环境互作方差
    # 缺点:各环境有相同的协方差
    # 环境作为固定效应+BLUP+每个地点的基因型与环境互作效应
    ansMain <- mmer(Yield~Env,
                    random= ~ vs(Name, Gu=A) + vs(ds(Env),Name, Gu=A),
                    rcov= ~ units,
                    data=DT, verbose = FALSE)
    summary(ansMain)
    
    # 6. 非结构化模型
    # 假设存在基因型与环境互作
    # 非结构化模型可以得到尽可能多的环境到环境组合的协方差
    # 缺点:方差分量很大,方差组分很难收敛,一些方差协方差组分是零,且很难有良好的初始值
    # 环境作为固定效应+单环境BLUP(协方差调整)
    ansUS <- mmer(Yield~Env,
                  random= ~ vs(us(Env),Name, Gu=A),
                  rcov= ~ units,
                  data=DT, verbose = FALSE)
    summary(ansUS)
    
    # 7. 随机回归模型
    # 假设环境可以视为连续变量,因此,截距和斜率的方差组分可以被拟合
    # 方差分量的数量将依赖于Legendre多项式拟合的阶数(leg函数)
    GBIT.library("orthopolynom")
    DT$EnvN <- as.numeric(as.factor(DT$Env))
    ansRR <- mmer(Yield~Env,
                  random= ~ vs(leg(EnvN,1),Name),
                  rcov= ~ units,
                  data=DT, verbose = FALSE)
    summary(ansRR)
    # 此外,其他结构的方差协方差矩阵可以应用于这个多项式
    GBIT.library("orthopolynom")
    DT$EnvN <- as.numeric(as.factor(DT$Env))
    ansRR <- mmer(Yield~Env,
                  random= ~ vs(us(leg(EnvN,1)),Name),
                  rcov= ~ units,
                  data=DT, verbose = FALSE)
    summary(ansRR)
    
    # 8. 基因型环境互作协方差结构
    # 不常用,但1阶自回归和其他协方差结构可以应用于GEI模型
    # 
    E <- AR1(DT$Env) # can be AR1() or CS(), etc.
    rownames(E) <- colnames(E) <- unique(DT$Env)
    EA <- kronecker(E,A, make.dimnames = TRUE)
    ansCS <- mmer(Yield~Env,
                  random= ~ vs(Name, Gu=A) + vs(Env:Name, Gu=EA),
                  rcov= ~ units,
                  data=DT, verbose = FALSE)
    summary(ansCS)
    

    sommer使用直接反演(DI)算法,大数据集会非常缓慢。该包比较适合p>n,即随机效应水平大于材料数。1000个材料,2个重复,2000个记录,或者300个材料,100000个标记,sommer包能快速完成。