• R语言
  • 【求助】如何在R程序批量生成变量并调用赋值

dapengde 据我的经验,凡是需要用到 assign() 的情况,几乎一定是作者的数据结构没设计好。尤其是这种需要生成一大串 a1, a2, a3, ... 变量的情况。楼主需要说明一下为什么要这样做。全局变量是恶魔;若无必要,不要向全局环境中写变量。

    yihui tctcab 啊哈哈,我也觉得是,这样是不好,不知道提问者具体要解决啥问题。但这是不同层面的问题: 一个属于“道”,一个属于“技”。有时候懒得考虑优化,能转就行,费电脑就费吧,省人脑。

      dapengde 若只是费电脑也就罢了,关键是这样悄么几创造全局变量造成了冲突自己都不会发现,到头来还得一脸蒙蔽去查错。讲个我好些年前可能讲过的冷笑话:

      从前,有一群变量在一起聊天。

      第一个变量说,我的名字叫 x1,很好听!
      第二个变量说,我的名字叫 x2,很好听!
      第三个变量说,我的名字叫 x3,很好听!
      ……
      第十个变量说,我的名字叫 x10,很好听!
      第十一个变量说,你们慢慢聊,我先走了。

        yihui 没 get 到笑点,x11咋了?
        当然我一般避免这样命名变量。我的模型搞到最后筛选出的模型变量我都把它存在一个叫the.one的变量里,感觉好中二啊?

          dapengde 额,我是想把一列数据拆分成多个子集来存储,将子集赋值给生成的变量;所以想生成这些变量,还有一个小疑问,我批量生成的这些变量后在循环体中如何调用赋值呢??不可能一个个输入的呀

            tjmath
            按你的描述,身为一个有责任心的Ruser我觉得必须阻止初学R的小伙伴误入歧途。

            按你的描述写出来的代码是很危险的,楼上yihui 跟我之前都吐槽过了。我们来看看按你的思路的程序会有什么样的问题:
            1. 循环产生大量变量充斥workspace,可读性差,难以维护
            2. 数据难以再次利用。列数据的子集存入多个变量,难以保存,难以复用
            所以不要这样做。


            请在R里使用data.frame的数据结构进行工作,这样可以避免大部分问题。
            最基本做到:在对数据操作的时候,想象成所有数据都储存在一张表里,每一个数据点(observation)为一行,由不同的列变量(variable)进行描述。

            按你的描述,我觉得比较好的做法是做一个label列,作为该列数据的子集的标签。然后要使用每个子集的时候直接[或filter取子集就行了。
            举例:

            df
            
                a  b  label
            1   1  1 groupA
            2   2  2 groupA
            3   3  3 groupA
            4   4  4 groupA
            5   5  5 groupA
            6   6  6 groupB
            7   7  7 groupB
            8   8  8 groupB
            9   9  9 groupB
            10 10 10 groupB

            取子集

            df[df$label=="groupA"]
            
              a b  label
            1 1 1 groupA
            2 2 2 groupA
            3 3 3 groupA
            4 4 4 groupA
            5 5 5 groupA

            求每个子集的a列的和,b列的和,最大值,最小值,中位

            library(dplyr)
            
            a %>%
              group_by(label) %>%
              summarise(suma=sum(a),sumb=sum(b),maxa=max(a),minb=min(b),mediana=median(a))
            
               label  suma  sumb  maxa  minb mediana
               <chr> <int> <int> <dbl> <dbl>   <int>
            1 groupA    15    15     5     1       3
            2 groupB    40    40    10     6       8

              tctcab 谢谢!!!刚刚接触R,写程序的习惯和思路都很乱,谢谢提醒,我去试试?

              11 天 后

              还是不太明白,我也有相似的问题,我要做的读入一段DNA序列,然后计算前n个的子序列中各个碱基的个数总和,并分别表示a [ i ] 的形式,应该用什么样的循环啊,自己编的程序太复杂,而且慢,请求各位大神指教,困扰很久了,谢谢?

                Isabel

                问对人了。
                如果是我的话,读入DNA序列并进行处理这种操作很常规,做之前会去先查一查有没有现成的工具可以用。

                包的名字叫seqinr,用的很多,网上搜搜教程应该有一大把
                举例:

                install.packages("seqinr")
                library(seqinr)
                
                # read a sequence
                
                url = "https://www.ncbi.nlm.nih.gov/sviewer/viewer.fcgi?id=1090936428&db=nuccore&report=fasta&extrafeat=0&fmt_mask=0&maxplex=1&sendto=t&withmarkup=on&tool=portal&log$=seqview&maxdownloadsize=1000000"
                seq <- seqinr::read.fasta(url)
                n1 <- seq$KU902450.1
                ## n1 looks like this:
                n1
                
                  [1] "t" "c" "t" "g" "a" "c" "t" "g" "c" "t" "t" "t" "t" "t" "c" "a" "c" "c" "c" "a" "t" "c" "t" "a" "c" "a" "g" "t" "c"
                 [30] "c" "c" "c" "c" "t" "t" "g" "c" "c" "g" "t" "c" "c" "c" "a" "a" "g" "c" "a" "a" "t" "g" "g" "a" "t" "g" "a" "t" "t"
                 [59] "t" "g" "a" "t" "g" "c" "t" "g" "t" "c" "c" "c" "c" "g" "g" "a" "c" "g" "a" "t" "a" "t" "t" "g" "a" "a" "c" "a" "a"
                ...
                # count number of nucleotides
                count(n1,1)
                 
                  a   c   g   t 
                 58 115  71  71 
                
                #count number of dinucleotides
                count(n1,2)
                 
                aa ac ag at ca cc cg ct ga gc gg gt ta tc tg tt 
                11 17 18 12 26 51  9 28 16 24 17 14  5 23 27 16 
                
                #GC content
                GC(n1)
                
                [1] 0.5904762

                R的强项就是几乎你想做的事情,几乎都能找到相关的包。以Bioconductor为代表的一系列工具更是必不可少的得力助手。
                所以动手之前多查一查吧~~避免把时间浪费在重复造轮子上

                恩呢,谢谢您,这几个包我正在学习,能不能请您帮我看一下这段代码,需要怎么改进,

                library(Biostrings)
                seq_a<-readDNAStringSet(file.choose(),"fasta") #读fasta文件
                seq<-seq_a[[1]]
                l<-length(seq)
                c<-rep(NA,l)
                g<-rep(NA,l)
                a<-rep(NA,l)
                t<-rep(NA,l)
                x<-rep(NA,l)
                y<-rep(NA,l)
                z<-rep(NA,l)
                for(i in 1:l){
                   cc<-letterFrequencyInSlidingView(seq,"C",view.width = 1)
                   c [ i ]<-sum(cc[1:i]) # 计算前 i 个字母中c的个数,并赋值给c [ i ]
                   gg<-letterFrequencyInSlidingView(seq,"G",view.width = 1)
                   g[ i]<-sum(gg[1:i])
                   aa<-letterFrequencyInSlidingView(seq,"A",view.width = 1)
                   a[ i]<-sum(aa[1:i])
                   tt<-letterFrequencyInSlidingView(seq,"T",view.width = 1)
                   t[ i ]<-sum(tt[1:i])
                   x [ i ]<-(a[ i]+g[ i])-(c [ i]+t[ i])
                   y [ i ]<-(a[ i]+c[ i ])-(g[ i]+t[ i])
                   z [ i ]<-(a[ i]+t[ i])-(c[ i]+g[ i])
                }