如何在R包中的函数中使用数据?

8
我目前正在编写一个R包的函数。这个函数的部分目的是(a)将数据作为输入,(b)检查其列是否符合可接受的值列表。
这些可接受的值由另一个组织提供给我。它们在一个.csv文件中。我想做的是加载这个.csv文件,并将其用作参考,以检查用户的列是否具有有效值。
例如,假设用户拥有以下数据:
set.seed(1839)
user <- data.frame(x=sample(letters,10),
                   y=rnorm(10))
user

   x          y
1  v -0.7025836
2  p -1.4586245
3  f  0.1987113
4  y  1.0544690
5  o -0.7112214
6  m  0.2956671
7  b  0.3016737
8  a -0.0945271
9  x -0.2790357
10 c  0.1681388

这个 .csv 文件包含许多(有用的)列,但我目前只关心其中一个(z):

ref <- data.frame(z=letters[1:4], a=rnorm(4), b=(rnorm(4)))
ref

  z          a          b
1 a -0.3563105  1.4536406
2 b  1.6841862  1.3232985
3 c  1.3073516 -0.6978598
4 d  0.4352904 -0.3971175

我想要运行的代码是(注意:实际函数中我没有调用library,这里只是为了简单起见):

library(dplyr)
valid_values <- ref %>%
  select(z) %>% 
  unname() %>% 
  unlist() %>% 
  as.character()

summary <- user %>% 
  mutate(x_valid=ifelse(x %in% valid_values, TRUE, FALSE))

summary 告诉我 user 中哪些 x 的值是有效的:

   x          y x_valid
1  v -0.7025836   FALSE
2  p -1.4586245   FALSE
3  f  0.1987113   FALSE
4  y  1.0544690   FALSE
5  o -0.7112214   FALSE
6  m  0.2956671   FALSE
7  b  0.3016737    TRUE
8  a -0.0945271    TRUE
9  x -0.2790357   FALSE
10 c  0.1681388    TRUE

现在,在我的函数代码中,我要用什么来替换ref?我应该在我的包中存储这些数据的哪个位置?我如何加载它?以及我应该将其转换为哪种类型的文件?
这个函数应该长成这样:
x_check <- function(data) {

  # get valid values
  valid_values <- ??? %>%
    select(z) %>% 
    unname() %>% 
    unlist() %>% 
    as.character()

  # compare against valid values
  return(
    data %>% 
    mutate(x_valid=ifelse(x %in% valid_values, TRUE, FALSE))
  )
}

我应该用什么替换掉???来获得我的数据?我不太在意用户是否能够看到这个ref数据。


我正在使用devtools::load_all("directory/for/my/package")来测试我的包。相关的会话信息:

R version 3.4.0 (2017-04-21)
Platform: x86_64-redhat-linux-gnu (64-bit)
Running under: Red Hat Enterprise Linux Server 7.3 (Maipo)

other attached packages:
[1] roxygen2_6.0.1             devtools_1.13.2

你有阅读过关于R软件包中如何包含数据的内容吗? - Gregor Thomas
2
通常情况下,您将数据存储在 data/ 文件夹中,使用 data() 加载它(如果它不是惰性加载)。您可以使用 devtools::use_data() 来为您设置。 - Gregor Thomas
@Gregor 是的,我确实仔细阅读了来自那个链接的Hadley关于它的章节。我已经将我的数据存储在data/文件夹中,并尝试使用devtools::use_data(admit_source.RData),其中admit_source是文件的名称,但我收到了错误提示:Error: Could not find package root. - Mark White
@Gregor 注意,DESCRIPTION 文件也指定了 LazyData: true - Mark White
我认为你需要更仔细地跟进链接,也许阅读一下 ?use_data - 你应该给 use_data 一个 R 对象,它会负责创建 RData 文件。如果你遇到这样的错误,也许你的工作目录没有设置到包文件夹?看起来你的问题是“为什么 use_data 不起作用?我怎样才能避免这个错误?”所有关于你的函数的东西似乎都不相关。 - Gregor Thomas
显示剩余2条评论
2个回答

14

我已经弄明白了,以防以后有人遇到相同问题。我是通过在函数内部从本地环境中的/data文件加载数据来完成这个操作的:

x_check <- function(data) {

  # get reference data
  data("ref", envir=environment())

  # get valid values
  valid_values <- ref %>%
    select(z) %>% 
    unname() %>% 
    unlist() %>% 
    as.character()

  # compare against valid values
  return(
    data %>% 
    mutate(x_valid=ifelse(x %in% valid_values, TRUE, FALSE))
  )
}

4
请查看Hadley Wickham关于R编写包的书籍,其中他解释了如何在包中存储数据

存储包数据的最常见位置是(惊喜!)data/。该目录中的每个文件都应为.RData文件,由save()创建,包含单个对象(与文件名相同)。

这将使您的数据集对包的任何用户都可以通过packagename::data进行访问。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接