什么是最有用的R技巧?

Dir*_*tel 88 r

为了分享R的一些提示和技巧,你最有用的功能或技巧是什么?聪明的矢量化?数据输入/输出?可视化和图形?统计分析?特殊功能?互动环境本身?

每个帖子一个项目,我们将看看我们是否通过投票获得了胜利者.

[编辑2008年8月25日]:所以一周后,似乎简单str()赢得了民意调查.因为我想自己推荐一个,这是一个容易接受的答案.

had*_*ley 64

str() 告诉你任何对象的结构.

  • 啊,`str`也是许多语言中`string`的缩写. (17认同)

jub*_*uba 64

我经常使用的一个非常有用的函数是dput(),它允许您以R代码的形式转储对象.

# Use the iris data set
R> data(iris)
# dput of a numeric vector
R> dput(iris$Petal.Length)
c(1.4, 1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.4, 1.5, 1.5, 1.6, 
1.4, 1.1, 1.2, 1.5, 1.3, 1.4, 1.7, 1.5, 1.7, 1.5, 1, 1.7, 1.9, 
1.6, 1.6, 1.5, 1.4, 1.6, 1.6, 1.5, 1.5, 1.4, 1.5, 1.2, 1.3, 1.4, 
1.3, 1.5, 1.3, 1.3, 1.3, 1.6, 1.9, 1.4, 1.6, 1.4, 1.5, 1.4, 4.7, 
4.5, 4.9, 4, 4.6, 4.5, 4.7, 3.3, 4.6, 3.9, 3.5, 4.2, 4, 4.7, 
3.6, 4.4, 4.5, 4.1, 4.5, 3.9, 4.8, 4, 4.9, 4.7, 4.3, 4.4, 4.8, 
5, 4.5, 3.5, 3.8, 3.7, 3.9, 5.1, 4.5, 4.5, 4.7, 4.4, 4.1, 4, 
4.4, 4.6, 4, 3.3, 4.2, 4.2, 4.2, 4.3, 3, 4.1, 6, 5.1, 5.9, 5.6, 
5.8, 6.6, 4.5, 6.3, 5.8, 6.1, 5.1, 5.3, 5.5, 5, 5.1, 5.3, 5.5, 
6.7, 6.9, 5, 5.7, 4.9, 6.7, 4.9, 5.7, 6, 4.8, 4.9, 5.6, 5.8, 
6.1, 6.4, 5.6, 5.1, 5.6, 6.1, 5.6, 5.5, 4.8, 5.4, 5.6, 5.1, 5.1, 
5.9, 5.7, 5.2, 5, 5.2, 5.4, 5.1)
# dput of a factor levels
R> dput(levels(iris$Species))
c("setosa", "versicolor", "virginica")
Run Code Online (Sandbox Code Playgroud)

当您寻求帮助或编辑或重新排序因子级别时,发布易于重现的数据块非常有用.


Rob*_*man 42

head()和tail()来获取数据帧,向量,矩阵,函数等的第一个和最后一个部分.特别是对于大数据帧,这是检查它已加载好的快速方法.


Dir*_*tel 38

一个很好的功能:读取数据使用的连接可以是本地文件,通过http访问的远程文件,来自其他程序的管道或更多.

作为一个简单的例子,考虑从random.org(它提供基于大气噪声的真实随机数而不是伪随机数发生器)的N = 10个随机整数(min = 100和max = 200)之间的这种访问:

R> site <- "http://random.org/integers/"         # base URL
R> query <- "num=10&min=100&max=200&col=2&base=10&format=plain&rnd=new"
R> txt <- paste(site, query, sep="?")            # concat url and query string
R> nums <- read.table(file=txt)                  # and read the data
R> nums                                          # and show it
   V1  V2
1 165 143
2 107 118
3 103 132
4 191 100
5 138 185
R>
Run Code Online (Sandbox Code Playgroud)

另外,随机包为访问random.org提供了几个便利功能.

  • 我必须同意,网站的一部分目的是为常见问题和一般资源提供最佳答案.提出问题并提供一个好的答案可以帮助支持一个主题.这对于诸如R的新/小标签特别有用. (8认同)
  • @Dirk:Jeff和Joel鼓励回答你自己的问题是完全可以接受的.没有要求,甚至没有非正式的要求,使你的答案CW.你显然没有游戏系统.再次,只是忽略社区维基警察. (4认同)
  • @ars:他可以自由地接受这个.如果他赢了,我也不会试图强迫他维基;不要接受我的建议.但是我不会在没有标记维基的情况下发布一个准备好的selfanswer,如果没有它,我也不会投票.把它拿走它的价值. (2认同)

Rei*_*son 35

我发现我使用with()within()越来越多.不再$浪费我的代码,并且不需要开始将对象附加到搜索路径.更严重的是,我发现with()等使我的数据分析脚本的意图更加清晰.

> df <- data.frame(A = runif(10), B = rnorm(10))
> A <- 1:10 ## something else hanging around...
> with(df, A + B) ## I know this will use A in df!
 [1]  0.04334784 -0.40444686  1.99368816  0.13871605 -1.17734837
 [6]  0.42473812  2.33014226  1.61690799  1.41901860  0.8699079
Run Code Online (Sandbox Code Playgroud)

with()设置一个评估R表达式的环境.within()做同样的事情,但允许您修改用于创建环境的数据对象.

> df <- within(df, C <- rpois(10, lambda = 2))
> head(df)
           A          B C
1 0.62635571 -0.5830079 1
2 0.04810539 -0.4525522 1
3 0.39706979  1.5966184 3
4 0.95802501 -0.8193090 2
5 0.76772541 -1.9450738 2
6 0.21335006  0.2113881 4
Run Code Online (Sandbox Code Playgroud)

我第一次使用时没有意识到的within()是你必须做一个赋值作为表达式的一部分,分配返回的对象(如上所述)以获得所需的效果.


Far*_*rel 34

数据输入技巧= RGoogleDocs包

http://www.omegahat.org/RGoogleDocs/

我发现Google电子表格是所有合作者在同一页面上的绝佳方式.此外,Google表单允许用户从受访者处获取数据,并毫不费力地将其写入Google电子表格.由于数据经常变化而且几乎从不是最终的,因此R直接阅读谷歌电子表格比下载csv文件并阅读它们更为可取.

# Get data from google spreadsheet
library(RGoogleDocs)
ps <-readline(prompt="get the password in ")
auth = getGoogleAuth("me@gmail.com", ps, service="wise")
sheets.con <- getGoogleDocsConnection(auth)
ts2=getWorksheets("Data Collection Repos",sheets.con)
names(ts2)
init.consent <-sheetAsMatrix(ts2$Sheet1,header=TRUE, as.data.frame=TRUE, trim=TRUE)
Run Code Online (Sandbox Code Playgroud)

我不能记下哪一个,但以下一个或两个命令需要几秒钟.

  1. getGoogleAuth

  2. getGoogleDocsConnection

  3. getWorksheets


Edu*_*oni 27

使用反引号来引用非标准名称.

> df <- data.frame(x=rnorm(5),y=runif(5))
> names(df) <- 1:2
> df
           1         2
1 -1.2035003 0.6989573
2 -1.2146266 0.8272276
3  0.3563335 0.0947696
4 -0.4372646 0.9765767
5 -0.9952423 0.6477714
> df$1
Error: unexpected numeric constant in "df$1"
> df$`1`
[1] -1.2035003 -1.2146266  0.3563335 -0.4372646 -0.9952423
Run Code Online (Sandbox Code Playgroud)

在这种情况下,df [,"1"]也可以.但是后面的滴答在公式内工作!

> lm(`2`~`1`,data=df)

Call:
lm(formula = `2` ~ `1`, data = df)

Coefficients:
(Intercept)          `1`  
     0.4087      -0.3440  
Run Code Online (Sandbox Code Playgroud)

[编辑] Dirk问为什么会给出无效的名字?我不知道!但我确实经常在实践中遇到这个问题.例如,使用hadley的重塑包:

> library(reshape)
> df$z <- c(1,1,2,2,2)
> recast(df,z~.,id.var="z")
Aggregation requires fun.aggregate: length used as default
  z (all)
1 1     4
2 2     6
> recast(df,z~.,id.var="z")$(all)
Error: unexpected '(' in "recast(df,z~.,id.var="z")$("
> recast(df,z~.,id.var="z")$`(all)`
Aggregation requires fun.aggregate: length used as default
[1] 4 6
Run Code Online (Sandbox Code Playgroud)

  • 当`check.names`为false时,它在`read.table`中也很有用 - 即当你想使用原始列名时. (3认同)

geo*_*try 25

不知道这是多么有名,但我肯定会利用的是环境的传递参考功能.

zz <- new.env()
zz$foo <- c(1,2,3,4,5)
changer <- function(blah) {
   blah$foo <- 5
}
changer(zz)
zz$foo
Run Code Online (Sandbox Code Playgroud)

对于这个例子来说,为什么它有用是没有意义的,但是如果你在它周围传递大型物体可以提供帮助.


小智 23

我最喜欢的是foreach库.它可以让你完成所有不错的应用程序,但语法更简单:

list_powers <- foreach(i = 1:100) %do% {
  lp <- x[i]^i
  return (lp)
}
Run Code Online (Sandbox Code Playgroud)

最好的部分是,如果您正在做一些实际需要大量时间的事情,您可以切换%do%%dopar%(使用适当的后端库)以立即并行化,甚至跨群集.非常光滑.


med*_*oll 19

我做了很多基本的数据操作,所以这里有两个内置函数(转换,子集)和一个我每天使用的库(sqldf).

创建样本销售数据

sales <- expand.grid(country = c('USA', 'UK', 'FR'),
                     product = c(1, 2, 3))
sales$revenue <- rnorm(dim(sales)[1], mean=100, sd=10)

> sales
  country product   revenue
1     USA       1 108.45965
2      UK       1  97.07981
3      FR       1  99.66225
4     USA       2 100.34754
5      UK       2  87.12262
6      FR       2 112.86084
7     USA       3  95.87880
8      UK       3  96.43581
9      FR       3  94.59259
Run Code Online (Sandbox Code Playgroud)

使用transform()添加列

## transform currency to euros
usd2eur <- 1.434
transform(sales, euro = revenue * usd2eur)

>
  country product   revenue     euro
1     USA       1 108.45965 155.5311
2      UK       1  97.07981 139.2125
3      FR       1  99.66225 142.9157
...
Run Code Online (Sandbox Code Playgroud)

使用subset()来切片数据

subset(sales, 
       country == 'USA' & product %in% c(1, 2), 
       select = c('product', 'revenue'))

>
  product  revenue
1       1 108.4597
4       2 100.3475
Run Code Online (Sandbox Code Playgroud)

使用sqldf()来切片并与SQL聚合

所述sqldf包提供了一个SQL接口R数据帧

##  recast the previous subset() expression in SQL
sqldf('SELECT product, revenue FROM sales \
       WHERE country = "USA" \
       AND product IN (1,2)')

>
  product  revenue
1       1 108.4597
2       2 100.3475
Run Code Online (Sandbox Code Playgroud)

执行聚合或GROUP BY

sqldf('select country, sum(revenue) revenue \ 
       FROM sales \
       GROUP BY country')

>
  country  revenue
1      FR 307.1157
2      UK 280.6382
3     USA 304.6860
Run Code Online (Sandbox Code Playgroud)

对于数据帧上更复杂的类似map-reduce的功能,请查看plyr包.如果发现自己想要拔掉头发,我建议用R检查Data Manipulation.


Edu*_*oni 18

?ave
Run Code Online (Sandbox Code Playgroud)

'x []'的子集被平均,其中每个子集由具有相同因子水平的那些观察组成.用法:ave(x,...,FUN = mean)

我用它所有的时间.(例如在这里答案)


Dan*_*Dan 18

一种加速代码和消除循环的方法.

而不是循环遍历数据框寻找值的循环.只需使用这些值的df的子集,更快.

而不是:

for(i in 1:nrow(df)){
  if (df$column[i] == x) {
    df$column2[i] <- y
    or any other similiar code
  }
}
Run Code Online (Sandbox Code Playgroud)

做这样的事情:

df$column2[df$column1 == x] <- y
Run Code Online (Sandbox Code Playgroud)

这个基本概念经常适用,是摆脱for循环的好方法

  • 这里有一个小陷阱,常常让我抓狂.如果df $ column1包含NA值,则使用==进行子集将拉出任何等于x*和*any NAs的值.要避免这种情况,请使用"%in%"而不是"==". (11认同)
  • 你的意思是'na.omit`?;) (2认同)

and*_*ewj 16

有时您需要rbind多个数据框. do.call()会让你这样做(当我问这个问题时,有人必须向我解释这个问题,因为它似乎没有明显的用处).

foo <- list()

foo[[1]] <- data.frame(a=1:5, b=11:15)
foo[[2]] <- data.frame(a=101:105, b=111:115)
foo[[3]] <- data.frame(a=200:210, b=300:310)

do.call(rbind, foo)
Run Code Online (Sandbox Code Playgroud)


dan*_*ank 16

一个R编程(不是交互式会话),我用if (bad.condition) stop("message")一个不少.每个函数都从其中的一些开始,当我完成计算时,我也将它们加入.我想我养成了assert()在C中使用的习惯.好处是双重的.首先,使用这些检查来获得工作代码要快得多.其次,也许更重要的是,当你在编辑器的每个屏幕上看到这些检查时,使用现有代码要容易得多.你不会想知道是否x>0或信任的评论指出,这是...你会知道,从一看,是这样的.

PS.我的第一篇文章.要温柔!

  • 这不是一个坏习惯,R提供了另一种方式:`stopfifnot(!bad.condition)`这更简洁. (12认同)

Cal*_*imo 13

traceback()当你在某个地方出现错误并且不易理解时,该函数是必须的.它将打印堆栈的跟踪,非常有用,因为R默认情况下不是很冗长.

然后设置options(error=recover)将允许您"输入"引发错误的函数并尝试理解究竟发生了什么,就像您完全控制它并且可以放入其中browser()一样.

这三个函数可以真正帮助调试代码.


Vin*_*nce 12

我真的很惊讶没有人发布关于申请,申请,lapply和sapply.我在R中做东西时使用的一般规则是,如果我有一个正在进行数据处理或模拟的for循环,我会尝试将其分解并用*apply替换它.有些人回避*apply函数,因为他们认为只能传入单个参数函数.没有什么可以进一步说实话!就像在Javascript中传递具有参数作为第一类对象的函数一样,您可以在R中使用匿名函数执行此操作.例如:

 > sapply(rnorm(100, 0, 1), round)
  [1]  1  1  0  1  1 -1 -2  0  2  2 -2 -1  0  1 -1  0  1 -1  0 -1  0  0  0  0  0
 [26]  2  0 -1 -2  0  0  1 -1  1  5  1 -1  0  1  1  1  2  0 -1  1 -1  1  0 -1  1
 [51]  2  1  1 -2 -1  0 -1  2 -1  1 -1  1 -1  0 -1 -2  1  1  0 -1 -1  1  1  2  0
 [76]  0  0  0 -2 -1  1  1 -2  1 -1  1  1  1  0  0  0 -1 -3  0 -1  0  0  0  1  1


> sapply(rnorm(100, 0, 1), round(x, 2)) # How can we pass a parameter?
Error in match.fun(FUN) : object 'x' not found


# Wrap your function call in an anonymous function to use parameters
> sapply(rnorm(100, 0, 1), function(x) {round(x, 2)})
  [1] -0.05 -1.74 -0.09 -1.23  0.69 -1.43  0.76  0.55  0.96 -0.47 -0.81 -0.47
 [13]  0.27  0.32  0.47 -1.28 -1.44 -1.93  0.51 -0.82 -0.06 -1.41  1.23 -0.26
 [25]  0.22 -0.04 -2.17  0.60 -0.10 -0.92  0.13  2.62  1.03 -1.33 -1.73 -0.08
 [37]  0.45 -0.93  0.40  0.05  1.09 -1.23 -0.35  0.62  0.01 -1.08  1.70 -1.27
 [49]  0.55  0.60 -1.46  1.08 -1.88 -0.15  0.21  0.06  0.53 -1.16 -2.13 -0.03
 [61]  0.33 -1.07  0.98  0.62 -0.01 -0.53 -1.17 -0.28 -0.95  0.71 -0.58 -0.03
 [73] -1.47 -0.75 -0.54  0.42 -1.63  0.05 -1.90  0.40 -0.01  0.14 -1.58  1.37
 [85] -1.00 -0.90  1.69 -0.11 -2.19 -0.74  1.34 -0.75 -0.51 -0.99 -0.36 -1.63
 [97] -0.98  0.61  1.01  0.55

# Note that anonymous functions aren't being called, but being passed.
> function() {print('hello #rstats')}()
function() {print('hello #rstats')}()
> a = function() {print('hello #rstats')}
> a
function() {print('hello #rstats')}
> a()
[1] "hello #rstats"
Run Code Online (Sandbox Code Playgroud)

(对于那些关注#rstats的人,我也在那里发布了这个).

请记住,使用apply,sapply,lapply,tapply和do.call!充分利用R的矢量化.你永远不应该走到一堆R代码,看看:

N = 10000
l = numeric()
for (i in seq(1:N)) {
    sim <- rnorm(1, 0, 1)
    l <- rbind(l, sim)
}
Run Code Online (Sandbox Code Playgroud)

这不仅不是矢量化的,而且R中的数组结构不像Python中那样增长(当空间耗尽时,IIRC的大小加倍).因此,每个rbind步骤必须首先增长到足以接受来自rbind()的结果,然后复制所有先前的内容.为了好玩,请在R中尝试上面的内容.注意它需要多长时间(您甚至不需要Rprof或任何计时功能).然后试试

N=10000
l <- rnorm(N, 0, 1)
Run Code Online (Sandbox Code Playgroud)

以下优于第一个版本:

N = 10000
l = numeric(N)
for (i in seq(1:N)) {
    sim <- rnorm(1, 0, 1)
    l[i] <- sim
}
Run Code Online (Sandbox Code Playgroud)


gap*_*ppy 11

根据Dirk的建议,我发布了一些例子.我希望他们不是太"可爱"[聪明,但我不在乎]或对这些观众微不足道.

线性模型是R的优点.当自变量的数量很高时,有两个选择.第一个是它使用lm.fit(),它接收设计矩阵x和响应y作为参数,类似于Matlab.这种方法的缺点是返回值是一个对象列表(拟合系数,残差等),而不是类"lm"的对象,可以很好地总结,用于预测,逐步选择等.方法是创建一个公式:

> A
           X1         X2          X3         X4         y
1  0.96852363 0.33827107 0.261332257 0.62817021 1.6425326
2  0.08012755 0.69159828 0.087994158 0.93780481 0.9801304
3  0.10167545 0.38119304 0.865209832 0.16501662 0.4830873
4  0.06699458 0.41756415 0.258071616 0.34027775 0.7508766
   ...

> (f=paste("y ~",paste(names(A)[1:4],collapse=" + ")))
[1] "y ~ X1 + X2 + X3 + X4"

> lm(formula(f),data=A)

Call:
lm(formula = formula(f), data = A)

Coefficients:
(Intercept)           X1           X2           X3           X4  
    0.78236      0.95406     -0.06738     -0.43686     -0.06644  
Run Code Online (Sandbox Code Playgroud)


Ric*_*ton 10

您可以指定从if-else块返回的值.

而不是,例如

condition <- runif(1) > 0.5
if(condition) x <- 1 else x <- 2
Run Code Online (Sandbox Code Playgroud)

你可以做

x <- if(condition) 1 else 2
Run Code Online (Sandbox Code Playgroud)

究竟这是如何工作的是深刻的魔力.

  • 您也可以像x < - ifelse(条件,1,2)那样执行此操作,在这种情况下,每个组件都是矢量化的. (6认同)

Joh*_*ohn 10

作为R的总菜鸟和统计数据的新手,我喜欢unclass() 将数据框的所有元素打印为普通列表.

一次性查看完整的数据集非常方便快速查看任何潜在问题.


Mat*_*ker 9

CrossTable()gmodels软件包中可以轻松访问SAS和SPSS风格的交叉表,以及常用的测试(Chisq,McNemar等).基本上,它xtabs()具有花哨的输出和一些额外的测试 - 但它确实使得与异教徒的共享输出更容易.


Pao*_*olo 7

确切地说system().能够从R环境内部访问所有unix工具(至少在Linux/MacOSX下),在我的日常工作流程中迅速变得非常宝贵.


Rya*_*rio 6

以下是将因子转换为数字的烦人解决方法.(与其他数据类型相似)

old.var <- as.numeric(levels(old.var))[as.numeric(old.var)]
Run Code Online (Sandbox Code Playgroud)

  • 或稍微更高效:`as.numeric(levels(old.var))[old.var]` (3认同)
  • 也许你的意思是"变成一个特征"的载体.在这种情况下,"as.character(old.var)"更简单. (2认同)

Ste*_*edy 6

虽然这个问题已经持续了一段时间,但我最近在SAS和R博客上发现了使用该命令的一个很棒的技巧cut.该命令用于将数据划分为类别,我将使用虹膜数据集作为示例,并将其分为10类:

> irisSL <- iris$Sepal.Length
> str(irisSL)
 num [1:150] 5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
> cut(irisSL, 10)
  [1] (5.02,5.38] (4.66,5.02] (4.66,5.02] (4.3,4.66]  (4.66,5.02] (5.38,5.74] (4.3,4.66]  (4.66,5.02] (4.3,4.66]  (4.66,5.02]
 [11] (5.38,5.74] (4.66,5.02] (4.66,5.02] (4.3,4.66]  (5.74,6.1]  (5.38,5.74] (5.38,5.74] (5.02,5.38] (5.38,5.74] (5.02,5.38]
 [21] (5.38,5.74] (5.02,5.38] (4.3,4.66]  (5.02,5.38] (4.66,5.02] (4.66,5.02] (4.66,5.02] (5.02,5.38] (5.02,5.38] (4.66,5.02]
 [31] (4.66,5.02] (5.38,5.74] (5.02,5.38] (5.38,5.74] (4.66,5.02] (4.66,5.02] (5.38,5.74] (4.66,5.02] (4.3,4.66]  (5.02,5.38]
 [41] (4.66,5.02] (4.3,4.66]  (4.3,4.66]  (4.66,5.02] (5.02,5.38] (4.66,5.02] (5.02,5.38] (4.3,4.66]  (5.02,5.38] (4.66,5.02]
 [51] (6.82,7.18] (6.1,6.46]  (6.82,7.18] (5.38,5.74] (6.46,6.82] (5.38,5.74] (6.1,6.46]  (4.66,5.02] (6.46,6.82] (5.02,5.38]
 [61] (4.66,5.02] (5.74,6.1]  (5.74,6.1]  (5.74,6.1]  (5.38,5.74] (6.46,6.82] (5.38,5.74] (5.74,6.1]  (6.1,6.46]  (5.38,5.74]
 [71] (5.74,6.1]  (5.74,6.1]  (6.1,6.46]  (5.74,6.1]  (6.1,6.46]  (6.46,6.82] (6.46,6.82] (6.46,6.82] (5.74,6.1]  (5.38,5.74]
 [81] (5.38,5.74] (5.38,5.74] (5.74,6.1]  (5.74,6.1]  (5.38,5.74] (5.74,6.1]  (6.46,6.82] (6.1,6.46]  (5.38,5.74] (5.38,5.74]
 [91] (5.38,5.74] (5.74,6.1]  (5.74,6.1]  (4.66,5.02] (5.38,5.74] (5.38,5.74] (5.38,5.74] (6.1,6.46]  (5.02,5.38] (5.38,5.74]
[101] (6.1,6.46]  (5.74,6.1]  (6.82,7.18] (6.1,6.46]  (6.46,6.82] (7.54,7.9]  (4.66,5.02] (7.18,7.54] (6.46,6.82] (7.18,7.54]
[111] (6.46,6.82] (6.1,6.46]  (6.46,6.82] (5.38,5.74] (5.74,6.1]  (6.1,6.46]  (6.46,6.82] (7.54,7.9]  (7.54,7.9]  (5.74,6.1] 
[121] (6.82,7.18] (5.38,5.74] (7.54,7.9]  (6.1,6.46]  (6.46,6.82] (7.18,7.54] (6.1,6.46]  (5.74,6.1]  (6.1,6.46]  (7.18,7.54]
[131] (7.18,7.54] (7.54,7.9]  (6.1,6.46]  (6.1,6.46]  (5.74,6.1]  (7.54,7.9]  (6.1,6.46]  (6.1,6.46]  (5.74,6.1]  (6.82,7.18]
[141] (6.46,6.82] (6.82,7.18] (5.74,6.1]  (6.46,6.82] (6.46,6.82] (6.46,6.82] (6.1,6.46]  (6.46,6.82] (6.1,6.46]  (5.74,6.1] 
10 Levels: (4.3,4.66] (4.66,5.02] (5.02,5.38] (5.38,5.74] (5.74,6.1] (6.1,6.46] (6.46,6.82] (6.82,7.18] ... (7.54,7.9]
Run Code Online (Sandbox Code Playgroud)


gap*_*ppy 5

另一招.有些软件包(如glmnet)将设计矩阵和响应变量作为输入.如果想要使特征之间的所有交互适合模型,则她不能使用公式"y~. ^ 2".使用expand.grid()允许我们利用R的强大的数组索引和向量操作.

interArray=function(X){
    n=ncol(X)
    ind=expand.grid(1:n,1:n)
    return(X[,ind[,1]]*X[,ind[,2]])
}

> X
          X1         X2
1 0.96852363 0.33827107
2 0.08012755 0.69159828
3 0.10167545 0.38119304
4 0.06699458 0.41756415
5 0.08187816 0.09805104

> interArray(X)
           X1          X2        X1.1        X2.1
1 0.938038022 0.327623524 0.327623524 0.114427316
2 0.006420424 0.055416073 0.055416073 0.478308177
3 0.010337897 0.038757974 0.038757974 0.145308137
4 0.004488274 0.027974536 0.027974536 0.174359821
5 0.006704033 0.008028239 0.008028239 0.009614007
Run Code Online (Sandbox Code Playgroud)

  • 如果建模函数不接受公式(这是非常罕见的!)用`model.matrix`构造设计矩阵不是更好吗? (3认同)

and*_*ewj 5

我最喜欢的一个,如果不是一些非正统的技巧,是使用eval()parse().这个例子可能说明了它如何有用

NY.Capital <- 'Albany'
state <- 'NY'
parameter <- 'Capital'
eval(parse(text=paste(state, parameter, sep='.')))

[1] "Albany"
Run Code Online (Sandbox Code Playgroud)

这种情况经常发生,并且使用eval()parse()可以帮助解决它.当然,我欢迎任何关于编写此代码的替代方法的反馈.

  • library(fortunes); fortune(106)如果答案是解析(),你通常应该重新思考这个问题. - Thomas Lumley R-help(2005年2月) (3认同)

Chr*_*ois 5

set.seed() 设置随机数生成器状态.

例如:

> set.seed(123)
> rnorm(1)
[1] -0.5604756
> rnorm(1)
[1] -0.2301775
> set.seed(123)
> rnorm(1)
[1] -0.5604756
Run Code Online (Sandbox Code Playgroud)


Jos*_*ich 5

对于那些写C从R调用的人来说.Internal(inspect(...))是很方便的.例如:

> .Internal(inspect(quote(a+2)))
  @867dc28 06 LANGSXP g0c0 [] 
  @8436998 01 SYMSXP g1c0 [MARK,gp=0x4000] "+"
  @85768b0 01 SYMSXP g1c0 [MARK,NAM(2)] "a"
  @8d7bf48 14 REALSXP g0c1 [] (len=1, tl=0) 2
Run Code Online (Sandbox Code Playgroud)