我正在通过教程学习R,但我在"如何阅读" R代码,这反过来使得编写R代码变得困难。例如:
dir.create(file.path("testdir2","testdir3"), recursive = TRUE)
VS
dup.names <- as.character(data.combined[which(duplicated(as.character(data.combined$name))), "name"])
虽然我知道这些代码行是什么,但我无法读取或解释每行代码的逻辑。我是从左到右还是从右到左阅读。读/写R代码时我应该使用哪些策略?
答案 0 :(得分:5)
<强> dup.names <- as.character(data.combined[which(duplicated(as.character(data.combined$name))), "name"])
强>
我在这里说实话。代码很糟糕。并且有很多原因。 很多人都不能读这样的一行,直观地知道输出是什么。 重点是你不应该编写你不理解的代码行。这不是Excel,你没有1条单行来适应所有内容。你有一个美味的大脚本,一个空的画布。使用该空间将您的代码分解成更小的位,从而制作出美丽的马赛克艺术作品!我们潜入〜
阅读一行代码就像看着熟悉的功能一样。你可以从左到右,从中到外阅读,只要你能锁定熟悉的东西。
好的,你看到data.combined
。你知道(希望)它有行和列......因为它是数据!
您在代码中发现$
并且知道它必须是data.frame。这是因为只有list和data.frames(实际上只是列表)允许您使用$
后跟列名来对列进行子集化。 子集 - 顺便说一句 - 只是意味着要看整体的一部分。在R中,可以使用单括号[
来完成data.frames和matrices的子集化,您将在其中看到[row, column]
。因此,如果我们输入data.combined[1,2]
,它将为您提供第2列第1行中的值。
现在,如果您知道第2列的名称为name
,则可以使用data.combined[1,"name"]
获取与data.combined$name[1]
相同的输出。回头看看那段代码:
<强> dup.names <- as.character(data.combined[which(duplicated(as.character(data.combined$name))), "name"])
强>
好的,现在我们看到我们的眼睛应该锁定data.combined[SOMETHING IS IN HERE?!])
并慢慢挑出data.combined[ ?ROW? , Oh the "name" column]
。凉。
<强> which(duplicated(as.character(data.combined$name)))
强>
只要您看到which
功能,它就会为您提供位置信息。示例:对于逻辑向量a = c(1,2,2,1)
,which(a == 1)
会为1
和4
提供1
在a
中的位置。
现在duplicated
也很简单。 duplicated(a)
(只是duplicated(c(1,2,2,1))
)会返回FALSE FALSE TRUE TRUE
。如果我们运行which(duplicated(a))
,则会返回3
和4
。现在这是一个你将要学习的秘密。如果您有TRUES和FALSES,则无需使用which
功能!所以也许which
在这里是无情的。还有as.character
...因为duplicated
适用于数字和字符串。
我是谁告诉你如何编写代码?但这是我的看法。 不要混淆子集的方式:使用EITHER data.frame [,column]或data.frame $ column ... 代码本可以更清晰地写成:
dupes <- duplicated(data.combined$name)
dupe.names <- data.combines$name[dupes]
或同等地:
dupes <- duplicated(data.combined[,"name"]
dupe.names <- data.combined[dupes,"name"]
我知道这很冗长,但我希望它有所帮助。
答案 1 :(得分:1)
“解开”长行代码一开始可能令人生畏。首先将其分解为括号,括号和逗号。括号直接添加到单词上表示一个函数,并且其中的任何逗号(除非它们是另一个嵌套函数或括号的一部分)单独的参数包含修改函数行为方式的参数。我们可以将第二行减少为外部函数as.character
及其参数:
dup.names <- as.character(argument_1)
就此而言,我们知道dup.names将被分配一个值data type "character"的单个参数。
第一行中的两个函数file.path()
和dir.create()
包含一个逗号来表示两个参数。参数可以是单个值,也可以使用等号指定。在这种情况下,file.path的输出恰好作为dir.create()
的参数#1执行。
file.path(argument_1,argument_2)
dir.create(argument_1,argument_2)
括号是一种对数据帧进行子集化的方法,使用dataframe_object [row,column]的一般表示法。在第二行中是数据框对象data.combined
。您知道它是一个数据框对象,因为括号直接添加到它上面,并且知道这一点可以让您知道内部的任何函数都有助于对此数据框进行子集化。
data.combined[row, column]
从那里,我们可以看到此括号内的内部函数将生成一个输出,指定将对该子集做出贡献的data.combined
行,并且只有名为"name"
的列才会生成被选中。
使用help function开始通过发现每个函数的作用以及它的参数是什么来解压缩这些行。
答案 2 :(得分:1)
阅读任何代码的更简单方法是分解它们的组件。
dup.names <-
as.character(
data.combined[which(
duplicated(
as.character(
data.combined$name
)
)
), "name"]
)
对于每个功能 - 那些带有圆括号的部分,例如: as.character()
您可以在控制台中输入?as.character
来了解有关他们的工作以及工作方式的更多信息
方括号[]
用于对数据帧进行子集化,这些数据帧存储在您的环境中(如果您在RStudio中使用R包含您的值以及任何已定义的函数,则右上角的框)。在这种情况下,您可以告诉data.combined
是在此示例中为此类数据框指定的名称(键入?data.frame
以查找有关数据框的更多信息)。