R语言中lapply()和sapply()的用法

  R语言中提供了一系列*apply()的函数,为数据分析中Split-Apply-Combine的策略提供了简洁方便的实现,这些函数的基本工作流程都是首先将数据按照某种规则划分(split)为较小的几部分,然后对各个部分应用(apply)某些操作,再将结果整合(combine)起来。关于Split-Apply-Combine策略的详细内容,可以参考Hadley Wickham的The Split-Apply-Combine Strategy for Data Analysis一文。

  在这些*apply()函数中,其中最重要的两个函数要数lappy()和sapply()了,下面将通过实例操作说明二者的主要功能。例子所用到的数据来源于UCI Machine Learning Repository (http://archive.ics.uci.edu/ml/datasets/Flags),其内容为各个国家的国旗的相关信息,可以在http://archive.ics.uci.edu/ml/machine-learning-databases/flags/flag.data下载到flag.data文件,将其导入R:

简要查看一下 flags 的内容:

1. lapply()

  lapply()中的“l”代表list,它接受list作为输入,并将指定的操作应用于列表中的所有元素。在上面的使用class()查看flags类型的时候,R返回flags的类型为data frame,data frame实际上是一个存储了若干vector的list,如果想知道flags中每一列的具体类型,就可以使用lapply(),对flags的每一列应用class()函数:

可见 ,lapply()返回一个list,其中包含了对flags各列应用class()的结果,注意 lapply(flags, class) 中的参数 class 末尾不需要加表示函数的小括号。上面的例子也暴露了一个问题,在控制台输出cls_list的时候,由于cls_list是一个list,打印出来一个很长的列表,不方便观看,可以使用 as.character(cls_list) 将cls_list转换为character的vector,获得较为紧凑的输出:

 2. sapply()

  sapply()中的代表simplify, 其与lapply()的不同之处在于sapply()会尝试对结果进行简化,使用sapply()替代lapply()重复前面例子的操作:

 可见sapply()自动将结果转换为了character的vector。具体来说,如果apply的结果是一个所有元素长度都为1的list,sapply()会将结果转换为vector;如果apply的结果是一个所有元素长度都相等且大于1的list,sapply()会将结果转换为matrix;如果sapply()无法判断简化规则,则不对结果进行简化,返回list,此时得到的结果和lapply()相同。