一道价值3199的R语言题

作者: 小洁忘了怎么分身 | 来源:发表于2019-06-15 22:31 被阅读87次

老板发来的R语言测试题目,让我一看就非常有胃口,如下:
http://www.bio-info-trainee.com/4458.html

他说,“如果你能独立完成这个题目,恭喜你,省了 3199 培训费,可以直接参加我们的单细胞线下培训啦”

(用三种方法做了的我灰常之开心)

首先看下题目开头的代码

set.seed(0.12345)n=26df=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替代,目标是这个样子:

image

<figcaption style="line-height: inherit; margin: 0px; padding: 0px; margin-top: 10px; text-align: center; color: rgb(153, 153, 153); font-size: 0.7em;"></figcaption>

脑子里第一个想法: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)=NULLrownames(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)=LETTERScolnames(mt)=NULLmt
##        [,1]       [,2]       [,3]       [,4]       [,5]## A 1.2629543 1.08576936 2.44136463 0.00000000 0.00000000## B 0.0000000 0.00000000 0.00000000 0.00000000 0.57671878## C 1.3297993 0.00000000 0.00000000 0.00000000 0.00000000## D 1.2724293 0.04672617 0.25014132 1.25408311 1.62544730## E 0.4146414 0.00000000 0.61824329 0.77214219 0.00000000## F 0.0000000 0.00000000 0.00000000 0.00000000 1.67829721## G 0.0000000 0.00000000 0.00000000 0.00000000 0.00000000## H 0.0000000 0.00000000 0.00000000 0.00000000 0.00000000## I 0.0000000 0.72675075 0.35872890 0.99698686 0.02538287## J 2.4046534 1.15191175 0.00000000 0.00000000 0.02747534## K 0.7635935 0.99216037 0.00000000 1.25601882 0.00000000## L 0.0000000 0.00000000 0.00000000 0.64667439 1.05375086## M 0.0000000 1.23830410 0.00000000 1.29931230 0.00000000## N 0.0000000 0.00000000 0.24226348 0.00000000 0.33561721## O 0.0000000 1.75790309 0.00000000 0.00837096 0.49479577## P 0.0000000 0.56074609 0.36594112 0.00000000 0.13805271## Q 0.2522234 0.00000000 0.24841265 0.59625902 0.00000000## R 0.0000000 0.00000000 0.06528818 0.11971764 0.19768426## S 0.4356833 0.00000000 0.01915639 0.00000000 0.00000000## T 0.0000000 0.00000000 0.25733838 1.45598840 0.00000000## U 0.0000000 0.00000000 0.00000000 0.22901959 0.00000000## V 0.3773956 1.15653700 0.00000000 0.99654393 1.58009168## W 0.1333364 0.83204713 0.66413570 0.78185918 1.49781876## X 0.8041895 0.00000000 1.10096910 0.00000000 0.26264546## Y 0.0000000 0.26613736 0.14377148 0.00000000 0.00000000## Z 0.5036080 0.00000000 0.00000000 0.04658030 0.00000000

方法三: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)=LETTERScolnames(my)=NULLmy
##        [,1]       [,2]       [,3]       [,4]       [,5]## A 1.2629543 1.08576936 2.44136463 0.00000000 0.00000000## B 0.0000000 0.00000000 0.00000000 0.00000000 0.57671878## C 1.3297993 0.00000000 0.00000000 0.00000000 0.00000000## D 1.2724293 0.04672617 0.25014132 1.25408311 1.62544730## E 0.4146414 0.00000000 0.61824329 0.77214219 0.00000000## F 0.0000000 0.00000000 0.00000000 0.00000000 1.67829721## G 0.0000000 0.00000000 0.00000000 0.00000000 0.00000000## H 0.0000000 0.00000000 0.00000000 0.00000000 0.00000000## I 0.0000000 0.72675075 0.35872890 0.99698686 0.02538287## J 2.4046534 1.15191175 0.00000000 0.00000000 0.02747534## K 0.7635935 0.99216037 0.00000000 1.25601882 0.00000000## L 0.0000000 0.00000000 0.00000000 0.64667439 1.05375086## M 0.0000000 1.23830410 0.00000000 1.29931230 0.00000000## N 0.0000000 0.00000000 0.24226348 0.00000000 0.33561721## O 0.0000000 1.75790309 0.00000000 0.00837096 0.49479577## P 0.0000000 0.56074609 0.36594112 0.00000000 0.13805271## Q 0.2522234 0.00000000 0.24841265 0.59625902 0.00000000## R 0.0000000 0.00000000 0.06528818 0.11971764 0.19768426## S 0.4356833 0.00000000 0.01915639 0.00000000 0.00000000## T 0.0000000 0.00000000 0.25733838 1.45598840 0.00000000## U 0.0000000 0.00000000 0.00000000 0.22901959 0.00000000## V 0.3773956 1.15653700 0.00000000 0.99654393 1.58009168## W 0.1333364 0.83204713 0.66413570 0.78185918 1.49781876## X 0.8041895 0.00000000 1.10096910 0.00000000 0.26264546## Y 0.0000000 0.26613736 0.14377148 0.00000000 0.00000000## Z 0.5036080 0.00000000 0.00000000 0.04658030 0.00000000

最后判断下三种方法得出的结果是否相同:

identical(mt,mx)
## [1] TRUE
identical(mt,my)
## [1] TRUE

吼。大功告成。

相关文章

  • 一道价值3199的R语言题

    老板发来的R语言测试题目,让我一看就非常有胃口,如下:http://www.bio-info-trainee.co...

  • GO语言学习初级之代码案例02

    GO语言学习之代码案例02 @(go语言 黑马)[GO语言] 爱因斯坦出的一道数学题 题目:爱因斯坦曾出过这样一道...

  • R语言作业-20题

    1.安装包 代码在 https://github.com/jmzeng1314/5years/blob/maste...

  • R语言作业-20题

    生信人的20个R语言习题 1 安装R包 2 了解ExpressionSet对象 CLL包里面就有data(sCLL...

  • R语言作业-20题

    教程对应B站:【生信技能树】生信人应该这样学R语言配套资料:B站的11套生物信息学公益视频配套讲义、练习题及思维导...

  • R语言初级10题

    说实话,这最简单的10道题我已经做了3遍了,每一遍都有新的体会。这一次我会把详细的记录下来,以供以后参考。 1.打...

  • 生信技能树 R语言 初级作业题目(上)

    之前都是没有系统地学习R语言,5月26日去西安听生信技能树 R语言培训课,Jimmy大神布置的作业题,像我这样纯正...

  • R的极客理想:工具篇(数据分析技术丛书).epub

    【下载地址】 大数据时代,R语言已成为数据分 析的利器,是挖掘数据价值必不可少的工具,截止到2014年5月,R语言...

  • R语言高级题作业笔记

    题目链接,生信菜鸟团:http://www.bio-info-trainee.com/3409.html高级题来来...

  • R语言初级题作业笔记

    题目链接:http://www.bio-info-trainee.com/3793.html题目比较基础,我这里就...

网友评论

    本文标题:一道价值3199的R语言题

    本文链接:https://www.haomeiwen.com/subject/cuvifctx.html