R语言-实用功能性语句3
目录概览
当对象是一个矩阵的时候,通常我们要获取其中一些元素。如果取出的正好是一行或者一列,此时,R会返回给我们一个向量,而不是矩阵。这会带来很大的麻烦,因为我们必须判断返回对象是向量,还是矩阵,才能继续下面的操作。此时,drop可以帮助我们,如果设置drop = FALSE,就会保持原样返回结果。
> b <- matrix(1:6, nrow = 2, ncol = 3)
> b
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> b[, 3]
[1] 5 6
> b[, 3, drop = FALSE]
[,1]
[1,] 5
[2,] 6
> b[1, , drop = FALSE]
[,1] [,2] [,3]
[1,] 1 3 5
在R中,逻辑运算符(logical operator)有 !, &, &&, |, ||, xor, is TRUE等等。
问题:&与&&, |与||有什么区别呢?它们是否是一致的呢?
答:否。我们将&和|称为短逻辑符,&&及||称为长逻辑符。长逻辑符只比较左边和右边的第一个元素,而短逻辑符会比较所有的。我们来看示例:
R中的逻辑运算符号有两组,|或者||(&或者&&),看起来觉得有些多余。其实,这是为了R独特的“向量运算”考虑的。|或者&首先考虑返回一个向量,而||和&&则只返回最后一个值。比如:
> c(FALSE, TRUE) | c(FALSE, FALSE)
[1] FALSE TRUE
> c(FALSE, TRUE) || c(FALSE, FALSE)
[1] FALSE
> a<-c(TRUE, FALSE, TRUE, FALSE)
> b<-c(FALSE, FALSE, TRUE, TRUE)
> c<-c(TRUE, FALSE, FALSE, FALSE)
> a & b
[1] FALSE FALSE TRUE FALSE
> a && b
[1] FALSE
> a & c
[1] TRUE FALSE FALSE FALSE
> a && c
[1] TRUE
> a | b
[1] TRUE FALSE TRUE TRUE
> a || b
[1] TRUE
> a | c
[1] TRUE FALSE TRUE FALSE
> a || c
R在解释代码时,不支持尾递归优化,所以在R中不要写递归。
在R绘图的图例中,通常需要“线条”和“点”分开单独表示,这里用到0和NA的小技巧。如果在legend()
函数函数中,pch = NA
表示没有点,lty=0
表示没有线条。
如果我们有一个字符字符串,现在需要将其转为可执行代码。方法如下:
> test1 = '1:3'
> test1
[1] "1:3"
> eval(parse(text = test1))
[1] 1 2 3
如果我们需要对一个factor的标签(label)进行转换,并且返回一个向量,有两种方法可以使用:
-
第一种方法,使用
c()
函数> tmp1 <- factor(rep(1:3, each = 3)) > tmp1 [1] 1 1 1 2 2 2 3 3 3 Levels: 1 2 3 > c(letters[1:3])[tmp1] [1] "a" "a" "a" "b" "b" "b" "c" "c" "c"
-
第二种方法,先转换标签,之后再使用as.character()函数。
> tmp2 <- factor(tmp1, labels = letters[1:3]) > tmp2 [1] a a a b b b c c c Levels: a b c > as.character(tmp2) [1] "a" "a" "a" "b" "b" "b" "c" "c" "c"
> "+"(1, 2)
[1] 3
> '>'(1, 2)
[1] FALSE
> tmp1 = list()
> for(i in 1:10)
tmp1[[i]] = i:(i+1)
> tmp1
[[1]]
[1] 1 2
[[2]]
[1] 2 3
[[3]]
[1] 3 4
[[4]]
[1] 4 5
[[5]]
[1] 5 6
[[6]]
[1] 6 7
[[7]]
[1] 7 8
[[8]]
[1] 8 9
[[9]]
[1] 9 10
[[10]]
[1] 10 11
> sapply(tmp1, '[[', 2)
[1] 2 3 4 5 6 7 8 9 10 11
最后一个例子中,使用了[[,巧妙地取得了第二个元素。
在使用write.table()
命令输入一个data.frame对象时候,输入文件会加引号。这时,设定quote参数,write.table(..., quote = FALSE)
。
do.call(rbind, list)
> test1 <- rep(c('**a', 'b'), c(3, 4))
> test1
[1] "a" "a" "a" "b" "b" "b" "b"
> split(test1, factor(test1))
$a
[1] "a" "a" "a"
$b
[1] "b" "b" "b" "b"
sink()可以将R的对象输出到外部文档中,第一遍可能包括了系统信息,需要输出第二遍。一个典型的流程如下:
> sink(filename)
> test1
> sink()
R中for循环中,需要指定一个计数器,比如i in 1:10之类。R可以直接将一个向量用于计数,返回向量中对应的值,比如:
> tmp1 <- letters[1:10]
for (i in tmp1) {
print(i)
}
> [1] "a"
[1] "b"
[1] "c"
[1] "d"
[1] "e"
[1] "f"
[1] "g"
[1] "h"
[1] "i"
[1] "j"
> Reduce(union, list(letters[1:3], letters[1:4], letters[1:5]))
[1] "a" "b" "c" "d" "e"
需要安装和调用devtools包
# Load the R code from web url
> library(devtools)
> source_url('https://raw.githubusercontent.com/YulongNiu/FunFunc/master/test_two_proportion.R')
x <- mtcars
head(x)
# 将行名改成序号
rownames(x) <- 1:nrow(mtcars)
head(x)
# 将列名改成序号(方法1)
colnames(x) <- 1:ncol(mtcars)
head(x)
# 将列名改成序号(方法2)
names(x) <- 1:ncol(mtcars)
head(x)
ar <- array(data=1:27,dim=c(3,3,3),
dimnames=list(c("a","b","c"),c("d","e","f"),c("g","h","i"))
)
ar
#或者
dimnames(ar)[[3]] <- c("G","H","I")
ar
>
> ar <- array(data=1:27,dim=c(3,3,3),
+ dimnames=list(c("a","b","c"),c("d","e","f"),c("g","h","i"))
+ )
> ar
, , g
d e f
a 1 4 7
b 2 5 8
c 3 6 9
, , h
d e f
a 10 13 16
b 11 14 17
c 12 15 18
, , i
d e f
a 19 22 25
b 20 23 26
c 21 24 27
> #或者
> dimnames(ar)[[3]] <- c("G","H","I")
> ar
, , G
d e f
a 1 4 7
b 2 5 8
c 3 6 9
, , H
d e f
a 10 13 16
b 11 14 17
c 12 15 18
, , I
d e f
a 19 22 25
b 20 23 26
c 21 24 27
>
#批量运行包:
all.pcg <- c("data.table","ggplot2","rmarkdown","tidyr","stringr","ggfortify")
sapply(all.pcg, library, character.only = T)
req.pcg <- function(pcg){
new <- pcg[!(pcg %in% installed.packages()[, "Package"])]
if (length(new)) install.packages(new, dependencies = T)
sapply(pcg, require, ch = T)
}
req.pcg(all.pcg)
批量读取数据,有两种形式,读取一个目录下的所有文件,从数据库中读取多个表。
-
1.读取方式
##读取同一目录下的所有文件 path <- "F:/Rfile/OD-B/Data" ##文件目录 fileNames <- dir(path) ##获取该路径下的文件名 filePath <- sapply(fileNames, function(x){ paste(path,x,sep='/')}) ##生成读取文件路径 data <- lapply(filePath, function(x){ read.csv(x, header=T)}) ##读取数据,结果为list ##从数据库中读取数据类似上面,获取要数据库里的文件名,写个正则筛选文件名后for循环读取。
-
2.读取方式
批量读入就是“在一个循环里一个一个读”。如果你要读取的csv内容格式相同,即所有数据汇总到一个dataframe中,可以:
filenames <- list.files("~/你的文件夹.../", pattern = ".csv")
n <- length(filenames)
dat <- data.frame()
for (i in 1:n) {
dat <- rbind(dat, read.csv(filenames[i]))
}
- 3.读取方式
如果需要读的csv内容格式不同,则可以作为list存储:
filenames <- list.files("~/你的文件夹.../", pattern = ".csv")
datalist <- lapply(filenames, function(name) {
read.table(paste("~/你的文件夹.../", name, sep = ""))
})
-
4.读取方式
getwd() list.files() files_full <- list.files( , full.names = TRUE) dat <- data.frame() for (i in 1:300) { dat <- rbind(dat, read.csv(files_full[i])) }
R语言是函数式编程语言。在函数式编程语言中,大部分情况可以不用for循环。
files <- list.files(directory)
data <- lapply(files, function(file) {
read.csv(paste0(directory, file), stringsAsFactors = FALSE)
})
data_cbind <- Reduce(cbind, data)
对结果批量输出csv文件,其中data为list格式
outPath <- "F:/Rfile/OD-B/Consequence" ## 输出路径
out_fileName <- sapply(names(data),function(x){
paste(x, ".csv", sep='')}) ##csv格式
out_filePath <- sapply(out_fileName, function(x){
paste(outPath ,x,sep='/')}) ##输出路径名
## 输出文件
for(i in 1:length(data)){
write.csv(data[[i]], file=out_filePath[i], row.name=F)
}
©哈尔滨商业大学 银河统计工作室
银河统计工作室成员由在校统计、计算机部分师生和企业数据数据分析师组成,维护和开发银河统计网和银河统计博客(技术文档)。专注于数据挖掘技术研究和运用,探索统计学、应用数学和IT技术有机结合,尝试大数据条件下新型统计学教学模式。