楼主: 为你打伞^_^
4364 2

[程序分享] R循环语句 [推广有奖]

  • 1关注
  • 0粉丝

大专生

1%

还不是VIP/贵宾

-

威望
0
论坛币
677 个
通用积分
0.0000
学术水平
2 点
热心指数
2 点
信用等级
2 点
经验
3633 点
帖子
1
精华
0
在线时间
83 小时
注册时间
2015-5-25
最后登录
2024-4-7

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

问题1:比如两个变量i,j   

i=1:4    j=1:30

公式y=j+10i

计算出的y是矩阵

这个循环该怎么写呢?

解:

i <- 1:4; j <- 1:30;  # i and j

ni<- length(i); nj <- length(j)  # lengths of i and j

y <- matrix(NA, nj, ni) # initiate a matrix with nj rows and ni columns

for (k in 1:ni){

for (p in 1:nj){

y [p, k] <- i[k] * 10 + j[p]  # fill the matrix

}

}

一个更简洁的方法:

matrix(rep(i, each=nj) * 10+rep(j, ni), nj, ni)

问题2

例子1

## if与条件判断

fun.test <- function(a, b, method = "add"){

    if(method == "add") { ## 如果if或者for/while;

        res <- a + b       ## 等后面的语句只有一行,则无需使用花括号。

}

    if(method == "subtract"){

        res <- a - b

    }

    return(res)           ## 返回值

}

### 检验结果

fun.test(a = 10, b = 8, method = "add")

fun.test(a = 10, b = 8, method = "substract")

for循环有些时候是必须要用到的,for循环内部,往往需要用下标,访问数据内的一定元素,例如向量内的元素,这时候用方括号表示。一维的数据组合,或者数组,常常称为向量。二维的数据组合,往往称为矩阵,或者数据框。具体的访问方式主要是方括号内部有没有逗号的区别。for循环或者while循环有时候让人觉得比较困惑,可能需要专门的时间进行讲解。

例2

### for循环与算法

test.sum <- function(x)

{

    res <- 0               ###  设置初始值,在第一次循环的时候使用

    for(i in 1:length(x)){

        res <- res + x ## 这部分是算法的核心,

##总是总右面开始计算,结果存到左边的对象

    }

    return(res)

}

### 检验函数

a <- c(1,2,1,6,1,8,9,8)

test.sum(a)

sum(a)

无论是什么样的函数,算法才是最关键的。往往需要巧妙得设计算法,让函数快捷高效。

(3). 返回值。

返回值就是函数给出的结果。打个比方,编写一个函数,就像自己攒一个机器,例如现在攒好 一台豆浆机,该豆浆机要求输入大豆,输入的大豆就是参数, 返回的结果,就是豆浆。如果该豆浆机需要不停地输入大豆, 而不能产出豆浆,这样的机器就一定会被扔掉。函数也是一样的, 需要给出返回值。 R中默认的情况是将最后一句作为返回值。但是为了函数的可读性起见,应该尽量指名返回值。返回值用return()函数给出。 函数在内部处理过程中,一旦遇到return(),就会终止运行, 将return()内的数据作为函数处理的结果给出。

下面举例说明R函数的编写方法。

例3 计算标准差

sd2 <- function(x)

{

   # 异常处理,当输入的数据不是数值类型时报错   

   if(!is.numeric(x)){                          

      stop("the input data must be numeric!\n")

   }                                            

   # 异常处理,当仅输入一个数据的时候,告知不能计算标准差

   if(length(x) == 1){                          

      stop("can not compute sd for one number,

           a numeric vector required.\n")      

   }

   ## 初始化一个临时向量,保存循环的结果,

   ## 求每个值与平均值的平方  

   x2 <- c()

   ## 求该向量的平均值

   meanx <- mean(x)

   ## 循环

   for(i in 1:length(x)){   

       xn <- x - meanx  

       x2 <- xn^2

   }

      ## 求总平方和

   sum2 <- sum(x2)

   # 计算标准差

   sd <- sqrt(sum2/(length(x)-1))

   # 返回值

   return(sd)

}

## 程序的检验

## 正常的情况

sd2(c(2,6,4,9,12))

## 一个数值的情况

sd2(3)

## 输入数据不为数值类型时

sd2(c("1", "2"))

问题3

今天在做一个项目的时候发现R剔除重复值比较困难,百度之后找到了解决办法:如果有下列的数据

> a

  公司 比例

1    a  0.4

2    a  0.3

3    a  0.2

4    b  0.5

5    b  0.4

如果想仅保留每个公司的第一条数据,可使用如下方法

> duplicated(a$公司)

[1] FALSE  TRUE  TRUE FALSE  TRUE

> b<-duplicated(a$公司)

> a[!b,]

  公司 比例

1    a  0.4

4    b  0.5

如果是要完全去重呢?也就是去除公司和比例完全一样的行数据,则用如下方法:

> duplicated(paste(a$公司,a$比例))

[1] FALSE FALSE FALSE FALSE FALSE

> a[!duplicated(paste(a$公司,a$比例)),]

  公司 比例

1    a  0.4

2    a  0.3

3    a  0.2

4    b  0.5

5    b  0.4

问题4

R语言中的循环函数(Grouping Function) R语言中有几个常用的函数,可以按组对数据进行处理,apply, lapply, sapply, tapply, mapply,等。这几个函数功能有些类似,下面介绍下这几个函数的用法。

Apply

这是对一个Matrix或者Array进行某个维度的运算。其格式是:

Apply(数据,维度Index,运算函数,函数的参数)

对于Matrix来说,其维度值为2,第二个参数维度Index中,1表示按行运算,2表示按列运算。下面举一个例子:

m<-matrix(1:6,2,3)

构建一个简单的2行3列的矩阵,内容为:

     [,1] [,2] [,3]

[1,]   1    3    5

[2,]   2    4    6

如果我们要计算每一行的sum值,那么我们可以写为:apply(m,1,sum)[1]  9 12如果要计算每一列的mean值,那么改为:apply(m,2,mean)[1] 1.5 3.5 5.5假如某个值为NA,那么要忽略NA值,进行每一行的SUM怎么办呢?m[2,2]<-NA     [,1] [,2] [,3]

[1,]    1    3    5

[2,]    2   NA    6

apply(m,1,sum)

[1] 9 NA    本身sum函数有一个参数na.rm,我们可以将这个参数带人到apply函数中,作为第4个参数:apply(m,1,sum,na.rm=TRUE)

[1] 9  8    需要注意的是如果是Data Frame,那么系统会将其转为Matrix,如果所有Column不是数字类型或者类型不一致,导致转换失败,那么apply是运算不出任何一列的结果的。Lapply

前面说到apply是对于matrix和array的,针对list,我们可以使用lapply函数。该函数接收list,返回的结果也是一个list。其调用如下:Apply(数据,运算函数,函数的参数)对于Data Frame来说,如果不同的列有不同的数据类型,不能转换成Matrix,但是却可以转换成List,然后使用lapply函数。我们建立一个学生名字,年龄和成绩的Data Frame,然后统计平均年龄和平均成绩,由于name列不是数值类型,所以无法算平均值,所以我们可以对非数值的数据只取count数量。这里就需要用到自定义函数。函数可以是匿名函数,也可以是之前定义好的函数,由于这里逻辑简单,我们可以用匿名函数解决。s<-data.frame(name=c("Devin","Edward","Lulu"),age=c(30,33,29),score=c(95,99,90))

    name age score

1  Devin  30    95

2 Edward  33    99

3   Lulu  29    90

lapply(s,function(x){if(is.numeric(x)){mean(x)}else{length(x)}})

$name

[1] 3

$age

[1] 30.66667

$score

[1] 94.66667我们可以看到返回了一个List的结果,里面包含3个项,每个项是函数执行的结果。lapply返回的结果和传入的List的结构相同,传入多少个Item,返回的也是多少个Item。Sapply

Sapply函数和Lapply函数很类似,也是对List进行处理,只是在返回结果上,Sapply会根据结果的数据类型和结构,重新构建一个合理的数据类型返回。调用格式如下:Apply(数据,运算函数,函数的参数,simplify = TRUE, USE.NAMES = TRUE)对于其中的simplify参数,就是指明是否对返回的结果集重新组织,如果为FALSE,那么就相当于lapply了。{if(is.numeric(x)){mean(x)}else{length(x)}})

    name      age    score

3.00000 30.66667 94.66667


二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:循环语句

已有 1 人评分论坛币 学术水平 热心指数 信用等级 收起 理由
jiangbeilu + 20 + 2 + 2 + 2 精彩帖子

总评分: 论坛币 + 20  学术水平 + 2  热心指数 + 2  信用等级 + 2   查看全部评分

本帖被以下文库推荐

沙发
pkl 在职认证  发表于 2016-3-14 20:14:48 |只看作者 |坛友微信交流群
好帖,学习了。谢谢楼主无私分享自己经验。

使用道具

藤椅
xubaiwu 发表于 2018-9-12 10:17:56 |只看作者 |坛友微信交流群
y <- matrix(NA, nj, ni)
这里为什么有个NA缺省值呢

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-24 02:15