一道价值3199的R语言题
今天是生信星球陪你的第395天
大神一句话,菜鸟跑半年。我不是大神,但我可以缩短你走弯路的半年~
就像歌儿唱的那样,如果你不知道该往哪儿走,就留在这学点生信好不好~
这里有豆豆和花花的学习历程,从新手到进阶,生信路上有你有我!
花花写于2019.6.15
曾老板发来的R语言测试题目,让我一看就非常有胃口,如下:http://www.bio-info-trainee.com/4458.html
(用三种方法做出来的我兴高采烈)
首先看下题目开头的代码
set.seed(0.12345)
n=26
df=data.frame(LETTERS[1:n],rnorm(n),rnorm(n),
rnorm(n),rnorm(n),rnorm(n))
a=lapply(2:ncol(df), function(i){
x=df[,c(1,i)]
x=x[x[,2]>0,]
return(x)
})
a
## [[1]]
## LETTERS.1.n. rnorm.n.
## 1 A 1.2629543
## 3 C 1.3297993
## 4 D 1.2724293
## 5 E 0.4146414
## 10 J 2.4046534
## 11 K 0.7635935
## 17 Q 0.2522234
## 19 S 0.4356833
## 22 V 0.3773956
## 23 W 0.1333364
## 24 X 0.8041895
## 26 Z 0.5036080
##
## [[2]]
## LETTERS.1.n. rnorm.n..1
## 1 A 1.08576936
## 4 D 0.04672617
## 9 I 0.72675075
## 10 J 1.15191175
## 11 K 0.99216037
## 13 M 1.23830410
## 15 O 1.75790309
## 16 P 0.56074609
## 22 V 1.15653700
## 23 W 0.83204713
## 25 Y 0.26613736
##
## [[3]]
## LETTERS.1.n. rnorm.n..2
## 1 A 2.44136463
## 4 D 0.25014132
## 5 E 0.61824329
## 9 I 0.35872890
## 14 N 0.24226348
## 16 P 0.36594112
## 17 Q 0.24841265
## 18 R 0.06528818
## 19 S 0.01915639
## 20 T 0.25733838
## 23 W 0.66413570
## 24 X 1.10096910
## 25 Y 0.14377148
##
## [[4]]
## LETTERS.1.n. rnorm.n..3
## 4 D 1.25408311
## 5 E 0.77214219
## 9 I 0.99698686
## 11 K 1.25601882
## 12 L 0.64667439
## 13 M 1.29931230
## 15 O 0.00837096
## 17 Q 0.59625902
## 18 R 0.11971764
## 20 T 1.45598840
## 21 U 0.22901959
## 22 V 0.99654393
## 23 W 0.78185918
## 26 Z 0.04658030
##
## [[5]]
## LETTERS.1.n. rnorm.n..4
## 2 B 0.57671878
## 4 D 1.62544730
## 6 F 1.67829721
## 9 I 0.02538287
## 10 J 0.02747534
## 12 L 1.05375086
## 14 N 0.33561721
## 15 O 0.49479577
## 16 P 0.13805271
## 18 R 0.19768426
## 22 V 1.58009168
## 23 W 1.49781876
## 24 X 0.26264546
一个由数据框筛选非负数据而来的长短不一的列表。现在的需求是将列表a还原为整齐的矩阵,删除的负值用0替代,目标是这个样子:

脑子里第一个想法:for循环套ifelse。
向量和list都有一个非常美妙的用法,是从《R数据科学》里学来的:先定义一个空的列表/向量,然后每次循环向其中添加一个元素。
这个方法非常好用,永远感谢哈德雷蜀黍。
观察一下操作对象:列表a,可以发现他的每个元素都是数据框,并且行名是原数据框df的行号,只是缺少了几个。
那么就可以用到那个神奇的符号%in%
,用来作为if
的判断条件。
刚好只是分两个条件,所以可以用ifelse
函数。
ta =list()
m=vector()
for (j in 1:length(a)){
p=a[[j]][2]
for (i in 1:n){
m[i] <- ifelse(i %in% rownames(p),p[rownames(p)==as.character(i),],0)
}
ta[[j]] <- m
}
ta
## [[1]]
## [1] 1.2629543 0.0000000 1.3297993 1.2724293 0.4146414 0.0000000 0.0000000
## [8] 0.0000000 0.0000000 2.4046534 0.7635935 0.0000000 0.0000000 0.0000000
## [15] 0.0000000 0.0000000 0.2522234 0.0000000 0.4356833 0.0000000 0.0000000
## [22] 0.3773956 0.1333364 0.8041895 0.0000000 0.5036080
##
## [[2]]
## [1] 1.08576936 0.00000000 0.00000000 0.04672617 0.00000000 0.00000000
## [7] 0.00000000 0.00000000 0.72675075 1.15191175 0.99216037 0.00000000
## [13] 1.23830410 0.00000000 1.75790309 0.56074609 0.00000000 0.00000000
## [19] 0.00000000 0.00000000 0.00000000 1.15653700 0.83204713 0.00000000
## [25] 0.26613736 0.00000000
##
## [[3]]
## [1] 2.44136463 0.00000000 0.00000000 0.25014132 0.61824329 0.00000000
## [7] 0.00000000 0.00000000 0.35872890 0.00000000 0.00000000 0.00000000
## [13] 0.00000000 0.24226348 0.00000000 0.36594112 0.24841265 0.06528818
## [19] 0.01915639 0.25733838 0.00000000 0.00000000 0.66413570 1.10096910
## [25] 0.14377148 0.00000000
##
## [[4]]
## [1] 0.00000000 0.00000000 0.00000000 1.25408311 0.77214219 0.00000000
## [7] 0.00000000 0.00000000 0.99698686 0.00000000 1.25601882 0.64667439
## [13] 1.29931230 0.00000000 0.00837096 0.00000000 0.59625902 0.11971764
## [19] 0.00000000 1.45598840 0.22901959 0.99654393 0.78185918 0.00000000
## [25] 0.00000000 0.04658030
##
## [[5]]
## [1] 0.00000000 0.57671878 0.00000000 1.62544730 0.00000000 1.67829721
## [7] 0.00000000 0.00000000 0.02538287 0.02747534 0.00000000 1.05375086
## [13] 0.00000000 0.33561721 0.49479577 0.13805271 0.00000000 0.19768426
## [19] 0.00000000 0.00000000 0.00000000 1.58009168 1.49781876 0.26264546
## [25] 0.00000000 0.00000000
这个方法是最基础的,做完还需要将列表转换为矩阵。而且最后的列名很杂乱,需要删掉,行名应该是LETTERS
mx=as.matrix(data.frame(ta))
colnames(mx)=NULL
rownames(mx)=LETTERS
方法二,循环和sapply很配
apply
族的函数一直是非常高级的。列表变矩阵,我想起了sapply
。把刚才的代码写成函数,用sapply
即可一步到位。sapply
的用法很简单,两个参数,一个是object也就是列表的名字;一个是函数名称。意为对列表中的每个元素进行同样的操作,所以写函数的时候需要以列表的元素(在这个栗子中是数据框)为单位来写。
pd=function(x){
p=x[2]
for (i in 1:n){
m[i] <- ifelse(i %in% rownames(p),p[rownames(p)==as.character(i),],0)
}
print(m)
}
mt=sapply(a,pd)
## [1] 1.2629543 0.0000000 1.3297993 1.2724293 0.4146414 0.0000000 0.0000000
## [8] 0.0000000 0.0000000 2.4046534 0.7635935 0.0000000 0.0000000 0.0000000
## [15] 0.0000000 0.0000000 0.2522234 0.0000000 0.4356833 0.0000000 0.0000000
## [22] 0.3773956 0.1333364 0.8041895 0.0000000 0.5036080
## [1] 1.08576936 0.00000000 0.00000000 0.04672617 0.00000000 0.00000000
## [7] 0.00000000 0.00000000 0.72675075 1.15191175 0.99216037 0.00000000
## [13] 1.23830410 0.00000000 1.75790309 0.56074609 0.00000000 0.00000000
## [19] 0.00000000 0.00000000 0.00000000 1.15653700 0.83204713 0.00000000
## [25] 0.26613736 0.00000000
## [1] 2.44136463 0.00000000 0.00000000 0.25014132 0.61824329 0.00000000
## [7] 0.00000000 0.00000000 0.35872890 0.00000000 0.00000000 0.00000000
## [13] 0.00000000 0.24226348 0.00000000 0.36594112 0.24841265 0.06528818
## [19] 0.01915639 0.25733838 0.00000000 0.00000000 0.66413570 1.10096910
## [25] 0.14377148 0.00000000
## [1] 0.00000000 0.00000000 0.00000000 1.25408311 0.77214219 0.00000000
## [7] 0.00000000 0.00000000 0.99698686 0.00000000 1.25601882 0.64667439
## [13] 1.29931230 0.00000000 0.00837096 0.00000000 0.59625902 0.11971764
## [19] 0.00000000 1.45598840 0.22901959 0.99654393 0.78185918 0.00000000
## [25] 0.00000000 0.04658030
## [1] 0.00000000 0.57671878 0.00000000 1.62544730 0.00000000 1.67829721
## [7] 0.00000000 0.00000000 0.02538287 0.02747534 0.00000000 1.05375086
## [13] 0.00000000 0.33561721 0.49479577 0.13805271 0.00000000 0.19768426
## [19] 0.00000000 0.00000000 0.00000000 1.58009168 1.49781876 0.26264546
## [25] 0.00000000 0.00000000
rownames(mt)=LETTERS
colnames(mt)=NULL
方法三:merge 和sapply也很配
老板给提示说可以用match
。可我没有想出来match
怎么做,脑子里却蹦出了merge
!!!因为同样是匹配,我想,merge
可以拼接两个表格,可以保留所有数据,生成缺失值。然后用0来替换缺失值不就可以咯。
x=x=data.frame(LETTERS)
ma <- function(y){
k=merge(x, y, by.x = "LETTERS",by.y = "LETTERS.1.n.",all.x = TRUE)
k[is.na(k)==T] <- 0
print(k[,2])
}
my=sapply(a,ma)
## [1] 1.2629543 0.0000000 1.3297993 1.2724293 0.4146414 0.0000000 0.0000000
## [8] 0.0000000 0.0000000 2.4046534 0.7635935 0.0000000 0.0000000 0.0000000
## [15] 0.0000000 0.0000000 0.2522234 0.0000000 0.4356833 0.0000000 0.0000000
## [22] 0.3773956 0.1333364 0.8041895 0.0000000 0.5036080
## [1] 1.08576936 0.00000000 0.00000000 0.04672617 0.00000000 0.00000000
## [7] 0.00000000 0.00000000 0.72675075 1.15191175 0.99216037 0.00000000
## [13] 1.23830410 0.00000000 1.75790309 0.56074609 0.00000000 0.00000000
## [19] 0.00000000 0.00000000 0.00000000 1.15653700 0.83204713 0.00000000
## [25] 0.26613736 0.00000000
## [1] 2.44136463 0.00000000 0.00000000 0.25014132 0.61824329 0.00000000
## [7] 0.00000000 0.00000000 0.35872890 0.00000000 0.00000000 0.00000000
## [13] 0.00000000 0.24226348 0.00000000 0.36594112 0.24841265 0.06528818
## [19] 0.01915639 0.25733838 0.00000000 0.00000000 0.66413570 1.10096910
## [25] 0.14377148 0.00000000
## [1] 0.00000000 0.00000000 0.00000000 1.25408311 0.77214219 0.00000000
## [7] 0.00000000 0.00000000 0.99698686 0.00000000 1.25601882 0.64667439
## [13] 1.29931230 0.00000000 0.00837096 0.00000000 0.59625902 0.11971764
## [19] 0.00000000 1.45598840 0.22901959 0.99654393 0.78185918 0.00000000
## [25] 0.00000000 0.04658030
## [1] 0.00000000 0.57671878 0.00000000 1.62544730 0.00000000 1.67829721
## [7] 0.00000000 0.00000000 0.02538287 0.02747534 0.00000000 1.05375086
## [13] 0.00000000 0.33561721 0.49479577 0.13805271 0.00000000 0.19768426
## [19] 0.00000000 0.00000000 0.00000000 1.58009168 1.49781876 0.26264546
## [25] 0.00000000 0.00000000
rownames(my)=LETTERS
colnames(my)=NULL
最后判断下三种方法得出的结果是否相同:
identical(mt,mx)
## [1] TRUE
identical(mt,my)
## [1] TRUE
吼。大功告成。
简书:小洁忘了怎么分身
隔壁生信技能树公益视频合辑(学习顺序是linux,r,软件安装,geo,小技巧,ngs组学!)
国内看B站,教学视频链接:https://m.bilibili.com/space/338686099
友情链接:生信工程师入门最佳指南、学徒培养、资料大全
点击底部的“阅读原文”,获得更好的阅读体验哦😻
初学生信,很荣幸带你迈出第一步。
我们是生信星球,一个不拽术语、通俗易懂的生信知识平台。由于是2018年新号,竟然没有留言功能。需要帮助或提出意见请后台留言、联系微信或发送邮件到jieandze1314@gmail.com,每一条都会看到的哦~
请关注“恒诺新知”微信公众号,感谢“R语言“,”数据那些事儿“,”老俊俊的生信笔记“,”冷🈚️思“,“珞珈R”,“生信星球”的支持!