单行创建data.frame并且列相互依赖

时间:2012-12-02 12:40:34

标签: r dataframe

生成data.frames(特别是对于不可重现的SO问题)的一种非常罕见的情况是当一列依赖于另一列的(通常是随机的)值时。例如,如果想要一个data.frame来测试回归,那么有一些噪声线性依赖会很好:

n <- 100
x <- runif(n)
dat <- data.frame( x=x, y=x+runif(n) )
plot(y~x,data=dat)

y vs x

但是,我想在一行中完成(上面将计为两行,第一行创建x,第二行使用data.frame赋值中的x),理想情况下不会在全局环境中存放任何内容。

6 个答案:

答案 0 :(得分:5)

这是within

的简单解决方案
within(data.frame(x = runif(n)), y <- x + runif(n))

此命令y分配给全局环境(或父框架)。

答案 1 :(得分:3)

这是一种不会破坏很多程序员喜欢的“按行分配”规则的方法:

within(data.frame(row.names = 1:n), {x = runif(n); y = x + runif(n)})

其中data.frame(row.names = 1:n)用于创建具有正确行数的空data.frame,否则within会抱怨。

答案 2 :(得分:3)

这是一个解决方案,既不会出现ID'd的两个缺点。

library(data.table)
n <- 100

dat <- data.table(x = runif(n))[, y := x + runif(n)]

它自身的缺点是:

  1. 需要加载整个包裹。
  2. 变得有点丑陋(例如data.frame(data.table(......))如果你想要一个“普通的”data.frame返回。

答案 3 :(得分:3)

set.seed将需要使随机数在任何情况下都可重现,但模数可以尝试:

set.seed(123)
dat <- transform(data.frame(x = runif(10)), y = x + runif(10))

这给出了:

> dat
           x         y
1  0.2875775 1.2444109
2  0.7883051 1.2416393
3  0.4089769 1.0865476
4  0.8830174 1.4556508
5  0.9404673 1.0433920
6  0.0455565 0.9453815
7  0.5281055 0.7741932
8  0.8924190 0.9344786
9  0.5514350 0.8793557
10 0.4566147 1.4111184

答案 4 :(得分:2)

这是一个自定义函数,其工作方式类似于transform(或plyr::mutate),但不需要初始数据框。 (显然这对OP的问题没有帮助,因为没有人会有这个功能,但我认为其他人可能会感兴趣)

create <- function(...) {
  .data <- list()

  cols <- as.list(substitute(list(...))[-1])
  cols <- cols[names(cols) != ""] # Silently drop unnamed columns

  for(col in names(cols)) {
    .data[[col]] <- eval(cols[[col]], .data, parent.frame())
  }
  as.data.frame(.data)
}
create(x = runif(1:10), y = x + 1)

答案 5 :(得分:1)

这是我提出的最好的。它使用的东西是初学者R的常见错误,作为编写更紧凑代码的技巧。

dat <- data.frame( x<-runif(n), y=x+runif(n) )

这与@Tommy's tip on CodeGolf.SE的精神相似。

缺点是:

  1. 可能令人困惑。特别是因为这是一个常见的错误,并且在这种情况下可能会被专家代码审查员弄糊涂。
  2. 在父级(全局,大多数用例)环境中存放x,可能会覆盖其他一些变量。
  3. 修改

    @ WojciechSobala在评论中的解决方案值得在此处突出显示。只需将上述表达式包装在local

    dat <- local( data.frame( x<-runif(n), y=x+runif(n) ) )
    

    由于local的工作方式与evalq类似(例如,它评估给定环境中的表达式),但默认情况下它通过new.env()x在新环境中进行评估。在这个新环境中创建,而不是在全球环境中创建。