美文网首页数据、字符R处理
我不是真正的懂apply和function,或许压根儿没懂过

我不是真正的懂apply和function,或许压根儿没懂过

作者: 小梦游仙境 | 来源:发表于2020-06-12 17:58 被阅读0次

    一直看老大代码看得觉得可痛快了呢,刷刷地结果就出来了,到自己想做个芝麻大点儿的事,头发抓掉一大把,都弄不出来。有些时候,以为懂和会,只是没实际去用,等真到自己上手,用那个网络语形容-啥也不是。不墨迹啦,记录下。

    主要是想改一个表达矩阵里,那些小于0的数值变为0。变成apply和function的事情了,我是真的不会用。

    > #下面三行代码就是前两行觉得没问题呀,第三行就是不对,哎
    > dat[8,][dat[8,]< -1] <- 0
    > dat[9,][dat[9,]< -1] <- 0
    > apply(dat,1,function(x){x[x< -1] <- 0})
    > #问老大,一行代码搞定。就是下面这个。
    > dat[dat<0]=0
    

    新建一个小数据模拟上面的代码的问题

    > mm<- data.frame(aa=seq(1:5),
    +                 bb=c(4,5,0,1,2),
    +                 cc=rep(1,5))
    > 
    > mm
      aa bb cc
    1  1  4  1
    2  2  5  1
    3  3  0  1
    4  4  1  1
    5  5  2  1
    > #用了下面的两个函数,其实意思和前面的是一样的,结果依然是不对的。
    > apply(mm,1,function(x){x[x< 2] <- 'zz'})
    [1] "zz" "zz" "zz" "zz" "zz"
    > apply(mm,2,function(x){x[x< 2] <- 'zz'})
      aa   bb   cc 
    "zz" "zz" "zz" 
    > 
    
    

    上面的结果肯定不对,得再想想,搜索到一个很好的例子,其实之前也见过

    > #还是得回去再理解一下了。
    > #####################   点石举例  ##########################
    > #http://www.crickcollege.com/news/236.html
    > l1 <- c(4,9,16)
    > l2 <- c(25,36,49)
    > matrix <- cbind(l1,l2)
    > matrix_apply1 <- apply(matrix,1,sum)
    > matrix_apply1
    [1] 29 45 65
    > matrix_apply2 <- apply(matrix,2,sum)
    > matrix_apply2 
     l1  l2 
     29 110 
    > matrix_apply3 <- apply(matrix,1,sqrt)
    > matrix_apply3
       [,1] [,2] [,3]
    l1    2    3    4
    l2    5    6    7
    > matrix_apply4 <- apply(matrix,2,sqrt)
    > matrix_apply4
         l1 l2
    [1,]  2  5
    [2,]  3  6
    [3,]  4  7
    > #自定义函数(有一个自变量)
    > #将sqrt变为 function(x) MyFunction(x)。这一写法翻译成中文是,应用一个自变量为x的函数,这个函数(我之前定义过,起了名字)叫MyFunction,矩阵里的每一个元素(按照运算顺序)都是x。
    > myfun1 <- function(x){
    +   result <- 1+sqrt(x)
    +   return(result)
    + }
    > #结果成行
    > matrix_apply5 <- apply(matrix,1, function(x) myfun1(x))
    > matrix_apply5
       [,1] [,2] [,3]
    l1    3    4    5
    l2    6    7    8
    > #结果成列
    > matrix_apply6 <- apply(matrix,2, function(x) myfun1(x))
    > matrix_apply6
         l1 l2
    [1,]  3  6
    [2,]  4  7
    [3,]  5  8
    > #有两个自变量(有两个自变量)
    > myfun2 <- function(x,y){
    +   result <- sqrt(x)+y
    +   return(result)
    + }
    > matrix_apply7 <- apply(matrix,1, function(x) myfun2(x,10))
    > matrix_apply7
       [,1] [,2] [,3]
    l1   12   13   14
    l2   15   16   17
    > 
    > matrix_apply8 <- apply(matrix,2, function(x) myfun2(x,10))
    > matrix_apply8
         l1 l2
    [1,] 12 15
    [2,] 13 16
    [3,] 14 17
    > 
    > matrix_apply9 <- apply(matrix,1, function(y) myfun2(100,y))
    > matrix_apply9
       [,1] [,2] [,3]
    l1   14   19   26
    l2   35   46   59
    > 
    > matrix_apply10 <- apply(matrix,1, function(y) myfun2(100,y))
    > matrix_apply10
       [,1] [,2] [,3]
    l1   14   19   26
    l2   35   46   59
    > 
    
    > #返回这个新建的小数据mm。
    > mm
      aa bb cc
    1  1  4  1
    2  2  5  1
    3  3  0  1
    4  4  1  1
    5  5  2  1
    > 
    > #尝试(1)
    > fun1<- function(x){
    +   'zz' <- x<1
    +   return(x)
    + }
    > 
    > apply(mm,2,function(x)fun1(x))
         aa bb cc
    [1,]  1  4  1
    [2,]  2  5  1
    [3,]  3  0  1
    [4,]  4  1  1
    [5,]  5  2  1
    > 
    > #尝试(2)
    > fun2 <- function(x){
    +   'zz' <- x[x<1]
    +   return(x)
    + }
    > apply(mm,2,function(x)fun2(x))
         aa bb cc
    [1,]  1  4  1
    [2,]  2  5  1
    [3,]  3  0  1
    [4,]  4  1  1
    [5,]  5  2  1
    > 
    > #尝试(3)
    > fun3 <- function(x){
    +   x[x<1] <- 'zz'
    +   return(x)
    + }
    > apply(mm,2,function(x)fun3(x))
         aa  bb   cc 
    [1,] "1" "4"  "1"
    [2,] "2" "5"  "1"
    [3,] "3" "zz" "1"
    [4,] "4" "1"  "1"
    [5,] "5" "2"  "1"
    > apply(mm,1,function(x)fun3(x))
       [,1] [,2] [,3] [,4] [,5]
    aa "1"  "2"  "3"  "4"  "5" 
    bb "4"  "5"  "zz" "1"  "2" 
    cc "1"  "1"  "1"  "1"  "1" 
    > 
    > 
    > 
    > #尝试(4)如果不加return呢?
    > fun4 <- function(x){
    +   x[x<1] <- 'zz'
    + }
    > apply(mm,2,function(x)fun4(x))
      aa   bb   cc 
    "zz" "zz" "zz" 
    > #不加return就不行了,所以按照之前的写法如下,就不对
    > apply(mm,2,function(x){x[x<1] <- 'zz'})
      aa   bb   cc 
    "zz" "zz" "zz" 
    > #那么我思考的是,如果想要的结果是为了返回一个新生成的值,就要加一个return,这个return可以返回要的值
    > #尝试(5) 下面一句就轻松搞定了,是老大发给我的。
    > nn <- mm
    > nn[nn<1]='zz'
    > 
    
    

    但是还是不是理解,就把老大最近一篇公众号上的用了function函数看看,再理解下。

    > #https://mp.weixin.qq.com/s/qS0z23mMxJYpGfOvsO_TIQ
    > set.seed(123)
    > dat=data.frame(s1=rnorm(26),
    +                s2=rnorm(26),
    +                s3=rnorm(26),
    +                s4=rnorm(26))
    > rownames(dat)=LETTERS
    > dat['A',]
              s1       s2          s3
    A -0.5604756 0.837787 -0.04287046
             s4
    A 0.1813035
    > pos=match(c('D','G','Z'),rownames(dat))
    > apply(dat, 2, function(x){
    +   order(x,decreasing = T)[pos]
    + })
         s1 s2 s3 s4
    [1,] 11  7 24 12
    [2,]  7  9  6  6
    [3,] 18 17 20 22
    > 
    > #上面的这个function函数和apply函数我能不能按照刚才的步骤再拆一下,然后理解结果是要干什么
    > #
    > myfun11 <-function(x){
    +   order(x,decreasing = T)[pos]
    + }
    > apply(dat,2,function(x)myfun11(x))
         s1 s2 s3 s4
    [1,] 11  7 24 12
    [2,]  7  9  6  6
    [3,] 18 17 20 22
    > #上面的重新定义了一个myfun11以后,得到的这个结果也是能够运行出和老大直接apply(dat, 2, function(x){order(x,decreasing = T)[pos]})一样的结果的,是不是可以理解成,如果我要是想要新替换已有变量的时候,就一定要定义为一个变量,如果仅仅是输出一个结果就不用必须新定义一个变量了。或许我理解的也不对。
    > #上面的理解:我用function函数定义了一个myfun11函数,x是这个myfun11函数里面的变量,这个里面的x,指代的应该是dat里每一列中所有的元素。这个order是可以和sum函数类似的道理,可以用在对多个元素的处理上。
    > 
    
    

    再翻一个例子

    > #https://mp.weixin.qq.com/s/XQybC6W0aLrbyzHNvJnDvA
    > mycal<-function(x){
    + mean<-mean(x)
    + sd<-sd(x)
    + result <- list(mean=mean,sd=sd)
    + return(result)
    + }
    > x<-c(1,2,3,80)
    > mycal(x)
    $mean
    [1] 21.5
    
    $sd
    [1] 39.00855
    
    > 
    > mysave<-function(earn,spend,lost){
    +   save<- earn-spend-lost
    +   result <- list(save=save)
    +   return(result)
    + }
    > mysave(earn = 1000,spend = 80,lost = 10)
    $save
    [1] 910
    
    > 
    > myscore<-function(paper,attendence){
    +   score<- paper*0.7+attendence*.3
    +   result <- list(score=score)
    +   return(result)
    + }
    > myscore(paper = 92,attendence = 70)
    $score
    [1] 85.4
    

    还有很好的在代码的例子,再体会一下,技能树的推文里很多。我现在的理解是:这里function(x)里的x不和apply一起用的时候,就是可以是任意变量,可以是单个元素也可以是整体数据;如果是和apply函数一起用,代表的是那一行或那一列的所有元素。理解的可能不对,迷糊中,掐掉,只是记录。

    参考:

    相关文章

      网友评论

        本文标题:我不是真正的懂apply和function,或许压根儿没懂过

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