help(mean)
或简写为?mean
。dput()
等方法,以便他人可以获得您数据的精确副本。data()
查看内置数据集的全面列表。每个数据集都有一个简短的描述,并且可以通过?iris
等方式获取更多信息,例如用于R中的'iris'数据集。已安装的软件包可能包含其他数据集。初步说明:有时您可能需要特殊格式(例如因子、日期或时间序列)的类别。对于这些情况,可以使用诸如as.factor
、as.Date
、as.xts
等函数。 示例:
d <- as.Date("2020-12-30")
class(d)
# [1] "Date"
向量
x <- rnorm(10) ## random vector normal distributed
x <- runif(10) ## random vector uniformly distributed
x <- sample(1:100, 10) ## 10 random draws out of 1, 2, ..., 100
x <- sample(LETTERS, 10) ## 10 random draws out of built-in latin alphabet
矩阵
m <- matrix(1:12, 3, 4, dimnames=list(LETTERS[1:3], LETTERS[1:4]))
m
# A B C D
# A 1 4 7 10
# B 2 5 8 11
# C 3 6 9 12
set.seed(42) ## for sake of reproducibility
n <- 6
dat <- data.frame(id=1:n,
date=seq.Date(as.Date("2020-12-26"), as.Date("2020-12-31"), "day"),
group=rep(LETTERS[1:2], n/2),
age=sample(18:30, n, replace=TRUE),
type=factor(paste("type", 1:n)),
x=rnorm(n))
dat
# id date group age type x
# 1 1 2020-12-26 A 27 type 1 0.0356312
# 2 2 2020-12-27 B 19 type 2 1.3149588
# 3 3 2020-12-28 A 20 type 3 0.9781675
# 4 4 2020-12-29 B 26 type 4 0.8817912
# 5 5 2020-12-30 A 26 type 5 0.4822047
# 6 6 2020-12-31 B 28 type 6 0.9657529
id date group age type x
1 1 2020-12-26 A 27 type 1 0.0356312
2 2 2020-12-27 B 19 type 2 1.3149588
3 3 2020-12-28 A 20 type 3 0.9781675
筛选你的数据
要分享一个子集,可以使用 head()
、subset()
或索引 iris[1:4, ]
。然后将其包装在 dput()
中,以便让其他人能够立即在 R 中使用。 示例
dput(iris[1:4, ]) # first four rows of the iris data set
在你的问题中分享的控制台输出:
structure(list(Sepal.Length = c(5.1, 4.9, 4.7, 4.6), Sepal.Width = c(3.5,
3, 3.2, 3.1), Petal.Length = c(1.4, 1.4, 1.3, 1.5), Petal.Width = c(0.2,
0.2, 0.2, 0.2), Species = structure(c(1L, 1L, 1L, 1L), .Label = c("setosa",
"versicolor", "virginica"), class = "factor")), row.names = c(NA,
4L), class = "data.frame")
library()
)
- 在新的R会话中测试运行代码,以确保代码可运行。人们应该能够将你的数据和代码复制粘贴到控制台中,并得到与你相同的结果。
- 如果打开连接或创建文件,请添加一些代码来关闭它们或删除文件(使用unlink()
)
- 如果更改选项,请确保代码包含将其恢复为原始选项的语句。(例如:op <- par(mfrow=c(1,2)) ...some code... par(op)
)sessionInfo()
的输出可以非常有帮助。当谈论与其他应用程序的连接(无论是通过ODBC还是其他方式)时,还应提供这些应用程序的版本号,并尽可能提供设置的必要信息。rstudioapi::versionInfo()
来报告您的RStudio版本。packageVersion("包名称")
的输出来提供包的版本。
set.seed()
可以指定种子1,即R的随机数生成器的特定状态。这使得随机函数(例如sample()
、rnorm()
、runif()
等)始终返回相同的结果,例如:
set.seed(42)
rnorm(3)
# [1] 1.3709584 -0.5646982 0.3631284
set.seed(42)
rnorm(3)
# [1] 1.3709584 -0.5646982 0.3631284
1注意:set.seed()
的输出在R版本大于3.6.0和之前版本之间有所不同。请指定您用于随机过程的R版本,并不要感到惊讶,如果您按照旧问题进行操作时得到稍微不同的结果。为了在这种情况下得到相同的结果,您可以在set.seed()
之前使用RNGversion()
函数(例如:RNGversion("3.5.2")
)。
关于如何编写可重现的示例,这是我的建议(如何编写可重现的示例)。我尝试让它简短而精炼。《R4DS》中“工作流:获取帮助”的第9.2节是一个更近期的版本,还讨论了reprex包。
如果您提供一个可重现的示例,您很可能会得到有关R问题的良好帮助。可重现的示例允许其他人通过复制和粘贴R代码来重新创建您的问题。
为使示例可重现,您需要包括四个内容:所需的软件包、数据、代码以及您的R环境的描述。
程序包应该在脚本顶部加载,这样很容易看到示例需要哪些程序包。
将数据包含在电子邮件或Stack Overflow问题中的最简单方法是使用dput()
生成R代码以重新创建它。例如,要在R中重新创建mtcars
数据集,我会执行以下步骤:
dput(mtcars)
mtcars <-
然后粘贴。花点时间确保您的代码易于他人阅读:
确保使用了空格并且变量名简洁但具有说明性
使用注释指出问题所在
尽力删除与问题无关的所有内容。
代码越短,理解就越容易。
在代码注释中包含sessionInfo()
的输出。这概括了您的R环境,并使检查是否使用过时的程序包变得容易。
您可以通过启动一个新的 R 会话并将脚本粘贴进去来检查是否已经创建了可重现的示例。
在将所有代码放入电子邮件之前,请考虑将其放在 Gist github 上。这将为您的代码提供漂亮的语法高亮,并且您不必担心任何东西被电子邮件系统破坏。
tidyverse
中的 reprex
是一个很好的包,用于生成最小化的、可重现的示例代码:https://github.com/tidyverse/reprex - mt1022dput()
不幸地返回了一长串向量。 - Gracedput(mtcars)
的输出直接复制到剪贴板? - Julien就我个人而言,我更喜欢"一行代码"。例如:
my.df <- data.frame(col1 = sample(c(1,2), 10, replace = TRUE),
col2 = as.factor(sample(10)), col3 = letters[1:10],
col4 = sample(c(TRUE, FALSE), 10, replace = TRUE))
my.list <- list(list1 = my.df, list2 = my.df[3], list3 = letters)
数据结构应该模仿作者问题的思路,而不是完全照搬原有的结构。当变量不会重写我的变量或者像df
这样的函数时,我非常感激。
或者,你可以选择简单一些的方法,使用一个预先存在的数据集,比如:
library(vegan)
data(varespec)
ord <- metaMDS(varespec)
不要忘记提及你可能正在使用的任何特殊包。
如果你试图演示更大的对象,可以尝试
my.df2 <- data.frame(a = sample(10e6), b = sample(letters, 10e6, replace = TRUE))
如果您正在使用raster
包处理空间数据,可以生成一些随机数据。该包的vignette中可以找到许多示例,但这里提供了一个小技巧。
library(raster)
r1 <- r2 <- r3 <- raster(nrow=10, ncol=10)
values(r1) <- runif(ncell(r1))
values(r2) <- runif(ncell(r2))
values(r3) <- runif(ncell(r3))
s <- stack(r1, r2, r3)
如果你需要一些像sp
中实现的空间对象,你可以通过外部文件(如ESRI shapefile)在“空间”包中获取一些数据集(请查看任务视图中的空间视图)。library(rgdal)
ogrDrivers()
dsn <- system.file("vectors", package = "rgdal")[1]
ogrListLayers(dsn)
ogrInfo(dsn=dsn, layer="cities")
cities <- readOGR(dsn=dsn, layer="cities")
受到这个帖子的启发,现在我在需要发布到Stack Overflow时使用一个方便的函数reproduce(<mydata>)
。
如果myData
是您要复制的对象名称,请在R中运行以下命令:
install.packages("devtools")
library(devtools)
source_url("https://raw.github.com/rsaporta/pubR/gitbranch/reproduce.R")
reproduce(myData)
该函数是dput
的智能包装器,实现以下功能:
dput
输出objName <- ...
,以便可以轻松地复制粘贴,但是...# sample data
DF <- data.frame(id=rep(LETTERS, each=4)[1:100], replicate(100, sample(1001, 100)), Class=sample(c("Yes", "No"), 100, TRUE))
DF大约有100 x 102个数据。我想要抽取10行和一些指定列。
reproduce(DF, cols=c("id", "X1", "X73", "Class")) # I could also specify the column number.
This is what the sample looks like:
id X1 X73 Class
1 A 266 960 Yes
2 A 373 315 No Notice the selection split
3 A 573 208 No (which can be turned off)
4 A 907 850 Yes
5 B 202 46 Yes
6 B 895 969 Yes <~~~ 70 % of selection is from the top rows
7 B 940 928 No
98 Y 371 171 Yes
99 Y 733 364 Yes <~~~ 30 % of selection is from the bottom rows.
100 Y 546 641 No
==X==============================================================X==
Copy+Paste this part. (If on a Mac, it is already copied!)
==X==============================================================X==
DF <- structure(list(id = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 25L, 25L, 25L), .Label = c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y"), class = "factor"), X1 = c(266L, 373L, 573L, 907L, 202L, 895L, 940L, 371L, 733L, 546L), X73 = c(960L, 315L, 208L, 850L, 46L, 969L, 928L, 171L, 364L, 641L), Class = structure(c(2L, 1L, 1L, 2L, 2L, 2L, 1L, 2L, 2L, 1L), .Label = c("No", "Yes"), class = "factor")), .Names = c("id", "X1", "X73", "Class"), class = "data.frame", row.names = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 98L, 99L, 100L))
==X==============================================================X==
注意输出的整个内容都在一行中,而不是被分成多行段落。
这样做可以使 Stack Overflow 上的问题帖子更易于阅读,也更容易复制粘贴。
现在您可以指定输出文本占用的行数(即,您将粘贴到 Stack Overflow 上的内容)。使用lines.out=n
参数即可。例如:
reproduce(DF, cols=c(1:3, 17, 23), lines.out=7)
将产生以下结果:
==X==============================================================X==
Copy+Paste this part. (If on a Mac, it is already copied!)
==X==============================================================X==
DF <- structure(list(id = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 25L,25L, 25L), .Label
= c("A", "B", "C", "D", "E", "F", "G", "H","I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U","V", "W", "X", "Y"), class = "factor"),
X1 = c(809L, 81L, 862L,747L, 224L, 721L, 310L, 53L, 853L, 642L),
X2 = c(926L, 409L,825L, 702L, 803L, 63L, 319L, 941L, 598L, 830L),
X16 = c(447L,164L, 8L, 775L, 471L, 196L, 30L, 420L, 47L, 327L),
X22 = c(335L,164L, 503L, 407L, 662L, 139L, 111L, 721L, 340L, 178L)), .Names = c("id","X1",
"X2", "X16", "X22"), class = "data.frame", row.names = c(1L,2L, 3L, 4L, 5L, 6L, 7L, 98L, 99L, 100L))
==X==============================================================X==
reproduce
函数,是否需要运行 library(devtools);source_url("https://raw.github.com/rsaporta/pubR/gitbranch/reproduce.R")
? - Juliendput
的输出复制到一行中,请运行writeClipboard(paste(capture.output(dput(DF)), collapse = ""))
。 - Julien这里有一份很好的指南。
最重要的一点是: 提供可以运行以查看问题的小段代码。此时,可使用一个有用的函数dput()
,但如果您有非常大的数据集,则可能需要制作一个小样本数据集或仅使用前10行左右的数据。
编辑:
另外,请确保您已经自己确定了问题的位置。示例不应该是一个完整的R脚本,其中包含“第200行出错”。如果您使用R中的调试工具(我喜欢browser()
)和Google,则应该能够真正确定问题的位置,并在其中再现相同的错误。
R-help邮件列表有一个发布指南,其中涵盖了提问和回答问题的内容,包括生成数据的示例:
示例:有时候提供一个可以实际运行的小例子会有所帮助。例如:
如果我有一个矩阵x如下:
> x <- matrix(1:8, nrow=4, ncol=2,
dimnames=list(c("A","B","C","D"), c("x","y"))
> x
x y
A 1 5
B 2 6
C 3 7
D 4 8
>
如何将它转换为一个包含8行和三列的数据框,列名为'row'、'col'和'value',其中维度名称作为'row'和'col'的值,如下所示: > x.df
row col value
1 A x 1
...
(可能的答案是:
> x.df <- reshape(data.frame(row=rownames(x), x), direction="long",
varying=list(colnames(x)), times=colnames(x),
v.names="value", timevar="col", idvar="row")
)
重点是“小”。您应该尽力创建一个最小化的可复现示例,这意味着数据和代码应尽可能简单以解释问题。
编辑:漂亮的代码比丑陋的代码更容易阅读。请使用风格指南。
read.table
: df <- read.table(header=TRUE,
text="Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1 5.1 3.5 1.4 0.2 setosa
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
5 5.0 3.6 1.4 0.2 setosa
6 5.4 3.9 1.7 0.4 setosa
")
如果您无法这样做,则可能需要聘请顾问来解决您的问题...
编辑: 匿名化/混淆的两个有用SO问题:
到目前为止,回答中肯定已经涵盖了可复现性的部分。这仅是为了澄清一个问题:可重现的示例不能且不应该是问题的唯一组成部分。不要忘记解释你想让它看起来像什么以及你问题的轮廓,而不仅仅是你已经尝试过的方法。代码是不够的,你还需要用言语表达。
以下是我遇到问题的样本数据和函数的一部分,这是一个需要避免的可重现示例(从一个真实的示例中摘录,名称已更改以保护无辜者):
code
code
code
code
code (40 or so lines of it)
我该如何实现这个功能?
我有一种非常简单高效的方法来制作一个之前未提到的R代码示例。 首先,您可以先定义您的结构。例如:
mydata <- data.frame(a=character(0), b=numeric(0), c=numeric(0), d=numeric(0))
>fix(mydata)
然后您可以手动输入数据。对于小的例子而言,这是高效的方式。
dput(mydata)
的意思是将mydata对象转换为可复制的R语言代码并输出。 - GSeefor (d in data) {...}
这样循环使用。 - Léo Léopold Hertz 준영