这个函数在Linux和windows下都可用。
a = data.frame(1:9)
a <- edit(a)
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")
`switch`函数是R语言中效率很高的函数。语法为:
switch(expr,...)
expr是可能出现的值。例如
aName <- sample(c("张三","李四","王五"),1) # 抽取一个数字
print(switch(aName,
"张三"="first",
"李四"="second",
"王五"="third"))
两个数据集横向合并,又有相同的编号,可用merge()。
data_merge <- merge(dataframe1,dataframe2,by="id")
data_merge <- merge(dataframe1,dataframe2,by=c("id","room"))
doMC 包是 R 语言中的一个包,用于并行计算。它是foreach包的一个后端,允许用户通过多核处理器上的多线程来加速计算。doMC包实际上是multicore包的一个接口,后者是在Unix-like系统上进行并行计算的工具。使用doMC可以非常方便地在 R 中执行并行循环,提高数据分析和模型训练的效率。
直接使用install.packages("doMC")安装时,会提示R版本不可用。
需要采用下面的命令安装:
install.packages("doMC", repos="http://R-Forge.R-project.org")
列表是一个能组织值、向量、数据框、矩阵等的容器,可以把各种变量按照顺序组织在一起。
还是以表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程序比使用RStudio占用资源更低,稳定性也好一些。
进入R语言的官方网站,根据自己的所在地选择最适合的镜像站下载R(https://www.r-project.org/)。
我选择的是兰州大学开源学会镜像(https://mirror.lzu.edu.cn/CRAN/),根据动画操作下载,版本号可能会有不同。

如果电脑中已经安装了其他版本的R,建议先卸载,然后再安装。
安装时,安装目录建议去掉横线,有些程序不识别目录中的短横线,容易造成错误。

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

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

打开R,输入下列代码安装languageserver包,回车运行。
install.packages("languageserver")

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


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

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

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包能快速完成。