• 主页
  • 课程

    关于课程

    • 课程归档
    • 成为一名讲师
    • 讲师信息
    教学以及管理操作教程

    教学以及管理操作教程

    ¥1,000.00 ¥100.00
    阅读更多
  • 特色
    • 展示
    • 关于我们
    • 问答
  • 事件
  • 个性化
  • 博客
  • 联系
  • 站点资源
    有任何问题吗?
    (00) 123 456 789
    weinfoadmin@weinformatics.cn
    注册登录
    恒诺新知
    • 主页
    • 课程

      关于课程

      • 课程归档
      • 成为一名讲师
      • 讲师信息
      教学以及管理操作教程

      教学以及管理操作教程

      ¥1,000.00 ¥100.00
      阅读更多
    • 特色
      • 展示
      • 关于我们
      • 问答
    • 事件
    • 个性化
    • 博客
    • 联系
    • 站点资源

      生信星球

      • 首页
      • 博客
      • 生信星球
      • 一道价值3199的R语言题

      一道价值3199的R语言题

      • 发布者 weinfoeditor
      • 分类 生信星球
      • 日期 2019年6月15日
      测试开头

       今天是生信星球陪你的第395天


         大神一句话,菜鸟跑半年。我不是大神,但我可以缩短你走弯路的半年~

         就像歌儿唱的那样,如果你不知道该往哪儿走,就留在这学点生信好不好~

         这里有豆豆和花花的学习历程,从新手到进阶,生信路上有你有我!

      花花写于2019.6.15

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

      一道价值3199的R语言题
      健明

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

      (用三种方法做出来的我兴高采烈)

      首先看下题目开头的代码

      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替代,目标是这个样子:

      一道价值3199的R语言题

      脑子里第一个想法: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,每一条都会看到的哦~

      一道价值3199的R语言题

      测试结尾

      请关注“恒诺新知”微信公众号,感谢“R语言“,”数据那些事儿“,”老俊俊的生信笔记“,”冷🈚️思“,“珞珈R”,“生信星球”的支持!

      • 分享:
      作者头像
      weinfoeditor

      上一篇文章

      太相信自己,以至于怀疑R坏了
      2019年6月15日

      下一篇文章

      R画树状图:一种轻量级方法
      2019年6月18日

      你可能也喜欢

      8-1651673488
      生信零基础入门学习小组长期报名中(2022仍继续)
      7 4月, 2022
      2-1651673738
      简化版的ROC曲线
      21 2月, 2022
      8-1651674718
      支持向量机模型
      19 11月, 2021

      搜索

      分类

      • R语言
      • TCGA数据挖掘
      • 单细胞RNA-seq测序
      • 在线会议直播预告与回放
      • 数据分析那些事儿分类
      • 未分类
      • 生信星球
      • 老俊俊的生信笔记

      投稿培训

      免费

      alphafold2培训

      免费

      群晖配置培训

      免费

      最新博文

      Nature | 单细胞技术揭示衰老细胞与肌肉再生
      301月2023
      lncRNA和miRNA生信分析系列讲座免费视频课和课件资源包,干货满满
      301月2023
      如何快速批量修改 Git 提交记录中的用户信息
      261月2023
      logo-eduma-the-best-lms-wordpress-theme

      (00) 123 456 789

      weinfoadmin@weinformatics.cn

      恒诺新知

      • 关于我们
      • 博客
      • 联系
      • 成为一名讲师

      链接

      • 课程
      • 事件
      • 展示
      • 问答

      支持

      • 文档
      • 论坛
      • 语言包
      • 发行状态

      推荐

      • iHub汉语代码托管
      • iLAB耗材管理
      • WooCommerce
      • 丁香园论坛

      weinformatics 即 恒诺新知。ICP备案号:粤ICP备19129767号

      • 关于我们
      • 博客
      • 联系
      • 成为一名讲师

      要成为一名讲师吗?

      加入数以千计的演讲者获得100%课时费!

      现在开始

      用你的站点账户登录

      忘记密码?

      还不是会员? 现在注册

      注册新帐户

      已经拥有注册账户? 现在登录

      close
      会员购买 你还没有登录,请先登录
      • ¥99 VIP-1个月
      • ¥199 VIP-半年
      • ¥299 VIP-1年
      在线支付 激活码

      立即支付
      支付宝
      微信支付
      请使用 支付宝 或 微信 扫码支付
      登录
      注册|忘记密码?