R中的实用程序

在本教程中, 你将学习一些简单易用且经常在R编程语言中使用的函数和实用程序。首先, 我们将讨论一些与数学相关的函数。然后, 你将研究与R的数据结构更紧密相关的函数, 例如处理嵌套列表, 正则表达式, 时间和日期。
数学函数
让我们看一下使用几个数学函数的以下代码单元。
首先, 你将定义两个向量, 即同时包含正值和负值的x和y。

x < - c(1.1, -2.3, -4.5) y < - c(2.4, -44, -2.2)

print(x)

[1]1.1 -2.3 -4.5

print(y)

[1]2.4 -44.0-2.2

让我们采用两个向量x和y:
  • 取它们的绝对值
  • 将它们四舍五入到小数点后零位,
  • 每个加起来
  • 最后, 取两者的平均值。
mean(c(sum(round(abs(x))), sum(round(abs(y)))))

27.5

你如何将上述代码分成几小段, 并对每个功能进行微观分析。
  • abs()函数仅考虑向量x和y元素的正值或绝对值。
例如, 在应用x和y的abs()函数时, 你将期望所有正值, 如下所示。
abs(x)

  1. 1.1
  2. 2.3
  3. 4.5
abs(y)

  1. 2.4
  2. 44
  3. 2.2
  • 列表中的下一个函数是round()函数。除了舍入输入外, 它什么也没有做。它需要一个额外的参数, 你可以在其中指定要将输入四舍五入到多少小数位。在常规设置中, round()函数将输入四舍五入到小数点后零位。
例如, 在将round()函数应用于向量x和y之后, 输出将如下图所示:
round(x)

  1. 1
  2. -2
  3. -4
round(y)

  1. 2
  2. -44
  3. -2
  • sum()函数将仅计算向量或矩阵的元素之和。例如, 如果将行向量作为参数传递给sum函数, 则所有行向量元素的总和将作为标量返回。
在这种情况下, 将向量x和y传递给sum()函数。因此, R简单地计算向量元素的总和并返回标量作为输出。
sum(abs(round(x)))

7

sum(abs(round(y)))

48

  • 最后, mean()或average()函数将计算算术平均值。它将取一组数字的平均值, 将它们相加, 然后除以该组中的项数。
在这种情况下, mean()函数的输入是长度为2的行向量, 其中包含数字7和48。因此, 这两个值的平均值将是这些值的总和除以元素数, 即2 。
mean(c(7, 48))

27.5

这仍然很容易。是不是
现在, 让我们进入本教程的下一个最有趣的部分!
数据结构的功能
现在让我们来看一些数据结构, 例如列表和向量。在列表数据结构上进行操作, 反转列表以及将列表转换为向量的方法不同, 反之亦然。
下面的函数是list(), 或者可以说它是列表的列表, 也称为嵌套列表。它创建了一个元素列表, 其中可以包含逻辑值, 数字值和字符串。
在下面的示例中, 列表内有三个列表, 分别是log, ch和int_vec。它们每个都有数据类型或R对象, 它们是逻辑, 数字和字符串/字符。
list_define < - list(log = TRUE, ch = "hello_srcmini", int_vec = sort(rep(seq(8, 2, by = -2), times = 2)))

list_define

  • $ log
  • true
  • $ ch
  • ‘ hello_srcmini’
  • $ int_vec
  • 2 2 4 4 6 6 8 8
  • log只是逻辑运算符, TRUE或FALSE
  • ch是字符串hello_srcmini
  • int_vec是数值序列。
由于log和ch非常简单, 因此让我们仔细看一下int_vec。
int_vec = sort(rep(seq(8, 2, by = -2), times = 2))

int_vec

  1. 2
  2. 2
  3. 4
  4. 4
  5. 6
  6. 6
  7. 8
  8. 8
让我们逐步了解上面的表达式。
seq函数可产生从8到2的降序数字序列。
seq()函数的语法为:seq(x1, x2, by = y)
前两个参数x1和x2告诉R序列的范围, 即序列的开始和结束位置。 by参数指定在每个间隔处序列的增量或减量。
例如, 下面的代码行将生成一个从100到200的序列, 增量为20。
seq(100, 200, by = 20)

  1. 100
  2. 120
  3. 140
  4. 160
  5. 180
  6. 200
在我们的示例中, 序列函数将输出一个从8到2(含)的序列, 其递减步长为2, 这将返回长度为4的向量。
a = seq(8, 2, by = -2)

a

  1. 8
  2. 6
  3. 4
  4. 2
现在让我们了解rep函数。
它可以重复使用times函数的输入参数, 该参数通常是向量或列表, 该函数以整数作为参数, 并在输入或序列中重复多次。 rep函数接受两个参数:输入和你希望输入重复或复制的次数。
在示例中应用rep函数, 该函数是长度为4的向量, 将产生长度为8的输出向量。
b = rep(a, times = 2)

如果要重复向量或列表的每个元素而不是整个向量, 则可以选择时间, 即使用each参数。
通过使用和的明显差异是每个元素出现的模式不相同。
rep(a, each = 2)

  1. 8
  2. 8
  3. 6
  4. 6
  5. 4
  6. 4
  7. 2
  8. 2
最后但并非最不重要的一点是sort()函数。它是不言自明的通用函数, 用于对许多数据结构(如向量或列表)进行排序。它不仅限于数值, 还可以用于逻辑值和字符。默认情况下, 它将按升序对元素进行排序。
让我们将rep函数的输出放到sort函数中, 以获得最终输出。
sort(b)

  1. 2
  2. 2
  3. 4
  4. 4
  5. 6
  6. 6
  7. 8
  8. 8
大!因此, 你成功地解决了long_expression int_vec的问题, 它很容易地位于列表list_define中。
此外, 让我们找出列表list_define的内容, 你将使用str()函数。 R中的str()函数允许你显示R对象的结构。
str(list_define)

List of 3 $ log: logi TRUE $ ch: chr "hello_srcmini" $ int_vec: num [1:8] 2 2 4 4 6 6 8 8

让我们看一些很酷的R表达式:
  • 函数is可以用于检查数据结构的类型, 该数据结构返回逻辑并且在处理条件语句时可以派上用场。
is.list(list_define) #returns true if the argument passed is a list.

TRUE

而如果传递了不是列表的向量, 则返回FALSE, 如下面的单元格所示。
is.list(c(1, 2, 3)) #returns false since you passed a vector.

FALSE

  • 在R中将向量转换为列表非常简单。你所需要做的就是使用as函数, 后跟.list(), 然后将向量作为参数传递。这就是将向量转换为列表所需的全部工作。
vec_to_list < - as.list(c(1, 2, 3))

is.list(vec_to_list) #verify it with is.list()

TRUE

  • 另一方面, 可以使用取消列表功能将列表展开为向量。 R通过简单地展平整个列表结构并最终输出单个向量来进行此转换。
list_to_vec < - unlist(vec_to_list)

list_to_vec

  1. 1
  2. 2
  3. 3
与is.list()类似, 你可以使用is.vector()来查找给定的参数是否为向量。
is.vector(list_to_vec)

TRUE

让我们将大列表list_define转换为向量。这里要注意的是向量只能包含单个数据类型或R对象。因此, 逻辑值和数字值都将转换为字符串。
unlist(list_define)

  • 日志
  • ‘ 真正’
  • ch
  • ‘ hello_srcmini’
  • int_vec1
  • ‘ 2’
  • int_vec2
  • ‘ 2’
  • int_vec3
  • ‘ 4’
  • int_vec4
  • ‘ 4’
  • int_vec5
  • ‘ 6’
  • int_vec6
  • ‘ 6’
  • int_vec7
  • ‘ 8’
  • int_vec8
  • ‘ 8’
在进入下一个主题之前, 让我们看一下append()和rev()函数。
  • 顾名思义, append()函数允许你向现有或新的向量或列表追加或添加两个或多个向量或列表。
让我们尝试一下list_define列表上的append()函数。你会注意到该列表现在将由6个元素组成, 而不是3个元素, 因为你将相同的列表附加了自身。
str(append(list_define, list_define))

List of 6 $ log: logi TRUE $ ch: chr "hello_srcmini" $ int_vec: num [1:8] 2 2 4 4 6 6 8 8 $ log: logi TRUE $ ch: chr "hello_srcmini" $ int_vec: num [1:8] 2 2 4 4 6 6 8 8

  • 最后, 让我们借助R中的rev()函数反转或更改list_define列表的顺序。
str(rev(list_define))

List of 3 $ int_vec: num [1:8] 2 2 4 4 6 6 8 8 $ ch: chr "hello_srcmini" $ log: logi TRUE

常用表达
很多人发现正则表达式是一个需要学习的复杂主题。但是, 这不仅是R语言中的一个重要主题, 而且也是跨Python等各种编程语言的重要主题。包括R在内的许多编程语言都提供内置的正则表达式功能。
正则表达式可以在许多应用程序中使用, 并且派上用场, 特别是当你要预处理文本数据时。它用于各种自然语言处理(NLP)问题。
它也用于查询搜索引擎和文本编辑器。
正则表达式, 也称为regex或regexp或有理运算符, 是定义搜索模式的一系列字符。通常, 这些搜索模式被各种字符串搜索算法用于查找模式, 找到并替换模式或过滤匹配的模式。
让我们通过理解grep()和grepl()函数的使用来开始本主题。
为简单起见, 让我们定义一个长度为5的行向量animals_regex, 你将在上面学习如何应用正则表达式模式。
animals_regex < - c('cat', 'dog', 'cheetah', 'lion', 'mice')

首先, 让我们了解grepl()函数。 grepl()函数返回逻辑输出, 这意味着如果字符串与模式匹配, 则返回TRUE, 否则返回FALSE。
下面是grepl()函数的简单直观的语法, 其中第一个参数是你要匹配的模式, 而第二个参数是你要从中查找或过滤模式的字符串或输入。你现在可以忽略其余的参数。 grepl(pattern, x, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)让我们借助grepl()函数找出上述五个动物中的哪个具有c。
在这种情况下, 你正在寻找其中包含c的动物, 这直接意味着此处的模式不过是c本身。
grepl(pattern = 'c', x = animals_regex)

  1. true
  2. false
  3. true
  4. false
  5. true
从上面的输出中, 你可以观察到, 由于猫, 猎豹和老鼠中都有ac, 因此对vectors_regex中的那些索引返回TRUE, 而对于与模式c不匹配的索引则返回FALSE。 。
让我们找出以c开头的元素, 而不仅仅是名称中包含字符c的元素。
为此, 你需要做的就是在要查找的模式的开头使用$ ^ $(插入号)符号。
grepl(pattern = '^c', x = animals_regex) #only cat and cheetah start with `c`.

  1. true
  2. false
  3. true
  4. false
  5. false
因此, 从上面的输出中, 你可以看到由于仅cat和cheetah以c开头, 因此, 仅将那些位置返回为TRUE。
类似于$ ^ $符号, 可以在要查找的模式末尾使用$符号以匹配以指定模式结尾的元素。要找出以n结尾的动物, 你可以简单地使用n, 后跟$符号。
grepl(pattern = 'n$', x = animals_regex) #only lion ends with an `n`.

  1. false
  2. false
  3. false
  4. true
  5. false
注意:要了解有关正则表达式的更多信息, 只需在jupyter笔记本代码单元格中键入?regex, 就会弹出有关regex的文档。另外, 如果你想了解有关正则表达式的更多信息, 可以遍历此源, 该源为你提供了一种设计搜索模式的工具, 然后使你可以在输入字符串上对其进行测试。
  • 与grepl()函数类似, 有一个grep()函数, 它代替逻辑输出返回与给定模式匹配的向量/矩阵的索引。
grep()函数的语法与grepl()函数的语法完全相同, 并给出为:grep(pattern, x, ignore.case = FALSE, perl = FALSE, value = http://www.srcmini.com/FALSE, fixed = FALSE, useBytes = FALSE, invert = FALSE)让我们以与上面相同的示例为例, 但是这次将grep()函数应用到上面!
grep(pattern = 'c', x = animals_regex)

  1. 1
  2. 3
  3. 5
如你所料, 上面的输出返回cat, cheetah和mouse元素的索引, 而不是TRUE / FALSE。就是这样!
让我们使用which函数比较grep()和grepl()函数。 which()函数仅返回逻辑对象的TRUE索引的向量的索引。
现在, 如果将点连接起来, 你将理解, 由于grepl()函数具有返回逻辑对象的功能, 因此将其简单地传递给which()函数, 该函数随后将转换输出, 类似于你期望的结果来自grep()函数。
which(grepl(pattern = 'c', x = animals_regex))

  1. 1
  2. 3
  3. 5
与grepl()函数类似, grep()函数也知道如何处理不同类型的正则表达式模式。
如果你应用grep()函数来查找animals_regex向量中以n结尾的元素, 那么由于只有狮子以n结尾, 因此你会期望输出4, 如下所示。
grep(pattern = 'n$', x = animals_regex)

4

做得好!
你已经学习了正则表达式的一些基础知识, 例如如何从匹配给定模式的向量中过滤掉元素。然而, R不仅限于模式匹配。它具有少数功能, 其中sub()函数就是其中之一。
sub()函数不是过滤匹配的模式, 而是用其他字符串替换匹配项。让我们更深入地了解它!
  • sub()函数主要将三个参数作为输入:
    • 你要匹配的模式或正则表达式,
    • 替换值, 它将放置在向量的匹配元素上, 并且
    • x将在其上应用正则表达式的输入向量字符串。
语法如下所示:sub(pattern, replacement, x, ignore.case = FALSE, perl = FALSE, fixed = FALSE, useBytes = FALSE)这次我们还是以与上面相同的示例理解其功能!
sub(pattern = 'c', replacement = 'a', x = animals_regex)

  1. ‘ aat’
  2. ‘ 狗’
  3. ‘ heheetah’
  4. ‘ 狮子’
  5. “ 过多”
从上面的输出中, 你可以观察到猫绳被替换为aat, 猎豹绳被替换为aheetah, 而老鼠绳被转换为miae。对于这些元素, 模式已成功匹配。
另外, 请注意sub()仅在字符串中查找第一个匹配项, 这意味着如果字符串中有两个c, 则仅将第一个出现的c替换为a, 而第二个则保持不变。
如果仍然希望更好地替换向量字符串中模式的每个匹配项, 请使用gsub()函数, 该函数不在本教程的范围内!
在继续下一个主题之前, 让我们尝试一个有趣的表达式。
这次你将使用| (或)运算符, 它将尝试匹配任何已定义的模式, 如果匹配, 则将其替换为-。请记住, 由于使用了gsub()函数, 它将替换字符串中模式的每个单个匹配项。
gsub(pattern = 'c|d|l', replacement = '-', x = animals_regex) #animals with `c`, `d`, `l` gets replaced with `-`.

  1. ‘ -在’
  2. ” – 和”
  3. ‘ -heetah’
  4. ‘ -离子’
  5. ‘ I-E’
让我们进入今天教程的最后一个主题, 即时间和日期!
时间和日期
时间和日期信息在各种情况下都非常有用。例如, 假设你正在处理与计算机视觉相关的问题, 并且你想找出算法运行所在的FPS(每秒帧数)。在这样的用例中, 你可以使用Time对象找出计算机视觉算法的处理速度。对于其他特定问题, 例如时间序列预测和季节性研究, 可以充分利用R的潜力。
首先, 让我们使用Sys.Date()简单命令, 使用R快速打印今天的日期。此处的Sys指的是系统, 这意味着它返回日期的系统近似值。
Sys.Date()

2020-02-04
很简单, 不是吗?
R的时间和日期属于Date对象, 或者可以说数据类型为Date。可以使用你在R教程的” 数据类型” 中学习的类函数进行验证。
与Date函数类似, 你有一个time()函数, 该函数返回系统的当前时间, 实际上, 它同时返回时间和日期作为输出。
Sys.time()

[1] "2020-02-04 02:05:04 IST"

创建日期对象你学习了如何获取当前日期和时间。现在, 让我们了解如何通过传递纯字符串作为参数来创建其他日期的日期。
若要为1993年5月10日创建日期对象, 将使用以下语法:
date_may < - as.Date('1993-05-10') #converts character string to a date object

date_may

1993-05-10
class(date_may)

'Date'

这里要注意的重要一点是, 如果你尝试将年份与月份或日期互换, 则默认情况下, R的日期功能默认会要求你以YYYY-MM-DD格式输入日期。让我们尝试一下!
date_may < - as.Date('05-1993-10') #R follows the ISO date format by default

Error in charToDate(x): character string is not in a standard unambiguous format Traceback:1. as.Date("05-1993-10")2. as.Date.character("05-1993-10")3. charToDate(x)4. stop("character string is not in a standard unambiguous format")

但好处是, 你可以通过传递参数格式并相应地自定义它来显式更改格式。
date_may < - as.Date('05-1993-10', format = '%m-%Y-%d')

as.Date()函数将接受不同的日期格式, 但是最后, 它将把它转换回ISO日期格式, 你可以通过打印date_may变量来看到。
date_may

1993-05-10
date_may < - as.Date('05-10-1993', format = '%m-%d-%Y')

date_may

1993-05-10
日期算术如果你可以对R中的Date对象应用诸如加法和减法之类的数学运算, 那会不会很棒?
让我们在date_may变量中添加1, 你会发现它会在一天后显示日期。
date_may + 1

1993-05-11
很好, 从上述输出中可以看到, 添加一个将日期从1993年5月10日更改为1993年5月11日。类似地, 你可以从日期中减去一个。
假设你想找出自己与哥哥姐姐的生日之间的时差。
elder_sib < - as.Date('1989-03-21')

date_may - elder_sib

Time difference of 1511 days

恭喜你完成了本教程。
本教程对于渴望学习R中各种实用程序功能的初学者来说是一个很好的起点。作为一个很好的练习, 你可能想了解有关正则表达式的更多信息, 因为它们在各种应用程序中都被使用, 并且它们确实非常强大。清理或预处理文本数据时使用的工具。
请随时在下面的评论部分中提出与本教程相关的任何问题。
【R中的实用程序】如果你想了解有关R的更多信息, 请参加srcmini的Intermediate R课程。

    推荐阅读