在刚接触用代码行处理数据的时候,受到课题组的影响,是从shell入门的,具体说逃不过sed grep awk
,在这之前我只会用excel下的函数,excel下有个很好的垂直查找vertical lookup
,也就是vlookup
,用来快速匹配数据,硕士的时候也就是凭借这一个函数解决了2DGel上蛋白质点编号的统一。所以对vlookup
有着比较深的感情,可以说这一个函数是我数据分析工作的敲门砖。
回到shell,我当时发现shell命令的强大之后(用awk写了第一个条件筛选的命令)想怎么可以用shell命令实现vlookup
, 最终有了这篇awk实现excel vlookup,但是随着时间的推移,敲了越来越多的R和python代码,发现vlookup
确实有一定的局限,而且当时写的shell脚本也存在一定的问题,操作也比较麻烦,数据处理,还是dplyr
和pandas
比较强大,这里放一个新鲜的dplyr
脚本,当然不只有类似vlookup
的left_join
,还有right_join
, inner_join
, full_join
, 这次没有偷懒,打了getopt
,到时候直接Rscript Rjoin -...
dplyr 各种join
-
vlookup
其实就是给定一个index
,或者说key
,然后把另一个表里关于这个key
的内容找到具体操作:EXCEL入门必学的VLOOKUP函数相信我你终于可以学会了 -
dplyr
的各种join
可以这么理解(下表): emmmm,刚发现刘博之前发过一个帖子,这个更形象:R语言中dplyr包join函数之目前我看到过的最形象的教程- 如果把
表1
看成left
,表2
看成right
, 那么所谓left_join
就是保证表1
的key
的顺序和数量不变,把表2
中和表1-key
对应的value3, value4
给合并过来,如果表2
中没有key
中某一个值,这个值对应的表2
中的value
会写NA
-
right_join
参考left_join
就对了,就是按照表2
的key
顺序和数量合并表1
的 -
inner_join
就比较神奇了,和你想的差不多,inner_join会取表1
和表2
的key
值的交集,然后在按顺序把表1
,表2
与这个key
交集对应的value
值贴过来。 -
full_join
顾名思义,就是求并集,然后把两个表对应的value值合并过来。
- 如果把
表1
key | value1 | value2 |
---|---|---|
k1 | v1-1 | v2-1 |
k2 | v1-2 | v2-2 |
k3 | v1-3 | v2-3 |
.. | .. | .. |
kn | v1-n | v2-n |
表2
key | value3 | value4 |
---|---|---|
k1 | v3-1 | v4-1 |
k2 | v3-2 | v4-2 |
k3 | v3-3 | v4-3 |
.. | .. | .. |
kn | v3-n | v4-n |
脚本代码
首先确保你的R装了dplyr
包,如果没有,打开R或者Rstudio install.packages('dplyr')
########################################
# Prj: MyScript
# Assignment: dplyr-join
# Author: Shawn
#######################################
##=======step1 import library==========
suppressMessages(library(getopt))
##=======step2 args setting============
command=matrix(c(
'help', 'h', 0, 'logic', 'help information',
'method', 'm', 1, 'character', 'JoinMethod: left, right, inner, full; default: left(equals excel vlookup)',
'left', 'x', 1, 'character', 'left_file: the 1st file',
'right', 'y', 1, 'character', 'right_file: the 2nd file',
'key', 'k', 1, 'character', 'key(by): the colnames of key columns, makesure leftfile and rightfile have the same colnames of key column'
),byrow = T, ncol = 5)
args = getopt(command)
## help information
if (!is.null(args$help)) {
cat(paste(getopt(command, usage = T), "\n"))
q(status=1)
}
## default value
if (is.null(args$method)){
args$method = "left"
}
## functions
suppressMessages(library(dplyr))
options(stringsAsFactors = F)
method <- args$method
left <- args$left
right <- args$right
key <- args$key
Rjoin = function(method,left,right,key){
## input data
x = read.delim(file = left, header = T,
sep = "\t", quote = NULL)
y = read.delim(file = right, header = T,
sep = "\t", quote = NULL)
## join
if (method == "left") {
z = left_join(x,y, by = key)
} else if (method == "right") {
z = right_join(x,y, by = key)
} else if (method == "inner") {
z = inner_join(x,y, by = key)
} else if (method == "full") {
z = full_join(x,y, by = key)
}
## output
write.table(z,file = paste(left,right,method,key,".xls",sep = "_"),
sep = "\t",
quote = F,
row.names = F)
}
Rjoin(method = method,
left = left,
right = right,
key = key)
用法
windows:
复制上面的代码到代码编辑器或者Rstudio,或者记事本里保存成Rjoin.R,怎么运行脚本参考:
- 将R加入环境变量,并启动R脚本
- windows10建议开启内建的bash教程 然后装
miniconda
, 然后在conda下装R。
linux or macos:
复制上面的代码到代码编辑器或者Rstudio,或者记事本里保存成Rjoin.R, 打开终端chmod +x Rjoin.R
给脚本添加可执行权限。
注意事项:
- 两个要进行join的文件必须是
制表符分隔符
分隔的文件,由于总有你意想不到的奇葩文件出现,本来做了sep
这个可选参数,但是read.table
只认识逗号,制表符,空格等常规的,为了避免麻烦,不如统一了输入文件的格式,最简单的办法就是exce -> 另存为 -> 类型选择制表符分隔符的txt. - 你要合并的关键列(key)必须有相同的列名!这个没办法,
join
函数自带的by
就是通过相同列名
的column来合并的 - 如果自己在Rstudio中跑
function
的话,要求你要合并的两个数据表数据类型必须是dataframe
脚本执行
一共设置了4个参数(除了帮助外),
-
-m/--method:
你想怎么合并,后面跟"left", "right", "inner" "full"。 -
-l/--left:
左边的文件(第一个文件)。 -
-r/--right:
右边的文件 (第二个文件)。 -
-k/--key:
两个文件key那一列的列名。
## 看下帮助:
~ »Rscript /Users/shawnwang/02.MyScript/BioScript/01.R/Rjoin.R -h
Usage: /Users/shawnwang/02.MyScript/BioScript/01.R/Rjoin.R [-[-help|h]] [-[-method|m] <character>] [-[-left|x] <character>] [-[-right|y] <character>] [-[-key|k] <character>]
-h|--help help information ## 帮助
-m|--method JoinMethod: left, right, inner, full; default: left(equals excel vlookup) ## 选择方法
-x|--left left_file: the 1st file ## 左边的文件
-y|--right right_file: the 2nd file ## 右边的文件
-k|--key key(by): the colnames of key columns, makesure leftfile and rightfile have the same colnames of key column ## 查找关键列的列名
## 下面这段代码是a.txt 和 b.txt 的node1这一列的并集相关信息合并。
Rscript /Users/shawnwang/02.MyScript/BioScript/01.R/Rjoin.R -m "full" -x a.txt -y b.txt -k "node1"
done...继续搬砖去