Какой самый полезный трюк?

Чтобы поделиться еще несколькими советами и трюками для R , какова ваша самая полезная функция или трюк? Умная векторизация? Ввод / вывод данных? Визуализация и графика? Статистический анализ? Специальные функции? Сама интерактивная среда?

Один пункт за сообщение, и мы увидим, получим ли мы победителя посредством голосования.

[Редактировать 25 августа 2008]: Итак, через неделю кажется, что простая str() выиграла опрос. Поскольку я хотел бы рекомендовать это сам, это легкий ответ, чтобы согласиться.

str() указывает структуру любого объекта.

Одной очень полезной функцией, которую я часто использую, является 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") 

Очень удобно размещать легко воспроизводимые fragmentы данных, когда вы обращаетесь за помощью или редактируете или изменяете уровни фактора.

head () и tail (), чтобы получить первую и последнюю части данных, вектор, матрицу, функцию и т. д. Особенно с большими кадрами данных это быстрый способ проверить, что он загружен нормально.

Одна приятная особенность: Чтение данных использует соединения, которые могут быть локальными файлами, удаленные файлы, к которым осуществляется доступ через http, каналы из других программ или более.

В качестве простого примера рассмотрим этот доступ для N = 10 случайных чисел между min = 100 и max = 200 от random.org (который поставляет истинные случайные числа на основе атмосферного шума, а не генератора псевдослучайных чисел):

 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> 

В стороне случайный пакет предоставляет несколько удобных функций для доступа к random.org .

Я нахожу, что использую with() и within() все больше и больше. Нет больше $ littering моего кода, и не нужно начинать прикреплять объекты к пути поиска. Более серьезно, я обнаруживаю, что 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 

with() устанавливает среду, в которой вычисляется выражение R. within() делает то же самое, но позволяет вам изменять объект данных, используемый для создания среды.

 > df <- within(df, C <- rpois(10, lambda = 2)) > head(df) ABC 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 

Что-то, чего я не понимал, когда я впервые использовал within() является то, что вам нужно выполнить назначение как часть оцениваемого выражения и назначить возвращаемый объект (как указано выше), чтобы получить желаемый эффект.

Титка ввода данных = пакет RGoogleDocs

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

Я нашел таблицы Google, чтобы быть фантастическим способом для всех соавторов быть на одной странице. Кроме того, Google Forms позволяет захватывать данные от респондентов и легко записывать их в электронную таблицу google. Поскольку данные часто меняются и почти никогда не являются окончательными, для R лучше всего читать электронную таблицу google, а не загружать файлы csv и считывать их в futz.

 # Get data from google spreadsheet library(RGoogleDocs) ps <-readline(prompt="get the password in ") auth = getGoogleAuth("[email protected]", 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) 

Я не могу повторить, но одна или две из следующих команд занимают несколько секунд.

  1. getGoogleAuth

  2. getGoogleDocsConnection

  3. getWorksheets

Используйте обратные ссылки для ссылки на нестандартные имена.

 > 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 

В этом случае также будет работать df [, “1”]. Но обратные клещи работают внутри формул!

 > lm(`2`~`1`,data=df) Call: lm(formula = `2` ~ `1`, data = df) Coefficients: (Intercept) `1` 0.4087 -0.3440 

[Edit] Дирк спрашивает, почему можно было бы назвать недопустимые имена? Я не знаю! Но я определенно сталкиваюсь с этой проблемой на практике довольно часто. Например, используя пакет переадресации hasley:

 > 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 

Не знаю, насколько хорошо это известно / нет, но кое-что, что я определенно использовал, – это возможности передачи по ссылке.

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

Для этого примера не имеет смысла, почему это было бы полезно, но если вы проезжаете крупные объекты вокруг него, это может помочь.

Моя новая любимая вещь – библиотека foreach. Он позволяет вам выполнять все приятные приложения, но с несколько упрощенным синтаксисом:

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

Самое приятное то, что если вы делаете то, что на самом деле требует значительного времени, вы можете переключиться с %do% на %dopar% (с соответствующей библиотекой backend), чтобы мгновенно распараллелить даже в кластере. Очень гладкий.

Я делаю много базовых манипуляций с данными, поэтому здесь две встроенные функции ( преобразование , подмножество ) и одна библиотека ( 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 

используйте 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 ... 

используйте подмножество () для обработки данных

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

используйте 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 

Выполните агрегацию или 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 

Для более сложных функций масштабирования, связанных с уменьшением карты, в кадрах данных, проверьте пакет plyr . И если вы хотите вытащить свои волосы, я рекомендую проверить « Манипуляция данными» с помощью R.

 ?ave 

Подвыборы ‘x []’ усредняются, причем каждое подмножество состоит из этих наблюдений с одинаковыми уровнями факторов. Использование: ave (x, …, FUN = mean)

Я использую это все время. (например, в этом ответе здесь так )

Способ ускорения кода и исключения для циклов.

а не для циклов, которые проходят через фреймворк, ищущий значения. просто возьмите подмножество df с этими значениями намного быстрее.

поэтому вместо:

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

сделайте что-то вроде этого:

 df$column2[df$column1 == x] <- y 

эта базовая концепция применима чрезвычайно часто и является отличным способом избавиться от циклов

Иногда вам нужно rbind несколько фреймов данных. do.call() позволит вам это сделать (кто-то должен был объяснить это мне, когда bind задал этот вопрос, поскольку он не кажется очевидным).

 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) 

В программировании R (не интерактивные сеансы) я использую if (bad.condition) stop("message") много . Каждая функция начинается с нескольких из них, и когда я работаю с вычислениями, я тоже их переплющиваю. Наверное, я привык к использованию assert() в C. Преимущества в два раза. Во-первых, намного быстрее получить рабочий код с этими проверками. Во-вторых, и, что еще важнее, гораздо проще работать с существующим кодом, когда вы видите эти проверки на каждом экране своего редактора. Вам не нужно задаваться вопросом, есть ли x>0 , или доверять комментарию, заявив, что это … вы будете знать , с первого взгляда, что это так.

PS. мой первый пост здесь. Быть нежным!

Функция traceback() является обязательной, когда вы где-то ошибаетесь и не понимаете ее легко. Он будет печатать трассировку стека, очень полезно, так как R по умолчанию не очень многословно.

Затем параметры options(error=recover) позволят вам «войти» в функцию, поднимающую ошибку, и попытаться понять, что происходит точно, как если бы у вас был полный контроль над ней и мог установить в нее browser() .

Эти три функции могут действительно помочь отладить ваш код.

Я действительно удивлен, что никто не опубликовал информацию о применении, наводке, лапке и сильном использовании. Общее правило, которое я использую, когда делаю вещи в R, состоит в том, что если у меня есть цикл for, который выполняет обработку данных или моделирование, я пытаюсь его исключить и заменить на *. Некоторые люди уклоняются от функций * apply, потому что они думают, что могут быть переданы только функции одного параметра. Ничто не может быть дальше от истины! Подобно прохождению функций с параметрами в качестве объектов первого classа в 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" 

(Для тех, кто следует за #rstats, я также разместил это там).

Помните, что используйте, применяйте, сочтите, приложите, нарежьте и сделайте. Воспользуйтесь преимуществами векторизации R. Вы никогда не должны подходить к кучу кода R и видеть:

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

Мало того, что это не векторизованное, но структура массива в R не вырастает, как в Python (размер удвоения, когда пространство заканчивается, IIRC). Поэтому каждый шаг rbind должен сначала вырасти, чтобы принять результаты от rbind (), а затем скопировать все содержимое предыдущего l. Для удовольствия попробуйте приведенное выше в R. Обратите внимание, сколько времени потребуется (вам даже не понадобится Rprof или какая-либо функция синхронизации). Затем попробуйте

 N=10000 l <- rnorm(N, 0, 1) 

Следующее лучше, чем первая версия:

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

По совету Дирка я публикую отдельные примеры. Надеюсь, они не слишком «милые» [умные, но мне все равно] или тривиальны для этой аудитории.

Линейные модели – это хлеб с маслом R. Когда число независимых переменных велико, у вас есть два варианта. Во-первых, он использует lm.fit (), который получает матрицу дизайна x и ответ y в качестве аргументов, аналогично Matlab. Недостатком этого подхода является то, что возвращаемое значение представляет собой список объектов (установленные коэффициенты, остатки и т. Д.), А не объект classа «lm», который может быть хорошо скомпонован, используется для outlookирования, поэтапного выбора и т. Д. Второй подход создает формулу:

 > 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 

Вы можете присвоить значение, возвращаемое из блока if-else.

Вместо, например,

 condition <- runif(1) > 0.5 if(condition) x <- 1 else x <- 2 

ты можешь сделать

 x <- if(condition) 1 else 2 

Точно, как это работает, это глубокая магия.

Как полный noob для R и новичок в статистике, я люблю unclass() чтобы печатать все элементы фрейма данных как обычный список.

Это очень удобно для просмотра полного набора данных всего за один раз, чтобы быстро разглядеть любые потенциальные проблемы.

CrossTable() из пакета gmodels обеспечивает легкий доступ к кросс-таблицам в стиле SAS и SPSS вместе с обычными тестами (Chisq, McNemar и т. Д.). В принципе, это xtabs() с причудливым выходом и некоторыми дополнительными тестами – но это облегчает обмен информацией с язычниками.

Определенно system() . Уметь иметь доступ ко всем инструментам unix (по крайней мере, под Linux / MacOSX) изнутри среды R быстро становится бесценным в моем ежедневном рабочем процессе.

Вот раздражающее обходное решение для преобразования коэффициента в числовое. (Аналогично для других типов данных)

 old.var <- as.numeric(levels(old.var))[as.numeric(old.var)] 

Хотя этот вопрос был на некоторое время, я недавно обнаружил большой трюк в блоге SAS и R для использования команды cut . Команда используется для разделения данных по категориям, и я буду использовать dataset диафрагмы в качестве примера и разделить его на 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] 

Еще один трюк. Некоторые пакеты, такие как 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 

Одним из моих любимых, если не несколько неортодоксальных трюков, является использование eval() и parse() . Этот пример, возможно, иллюстрирует, как это может быть полезно

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

Этот тип ситуации встречается чаще, чем нет, и использование eval() и parse() может помочь решить проблему. Конечно, я приветствую любые отзывы об альтернативных способах кодирования.

set.seed() устанавливает состояние генератора случайных чисел.

Например:

 > set.seed(123) > rnorm(1) [1] -0.5604756 > rnorm(1) [1] -0.2301775 > set.seed(123) > rnorm(1) [1] -0.5604756 

Для тех, кто пишет C для .Internal(inspect(...)) из 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 

d = ‘~ / R Код / Библиотека /’

files = list.files (d, ‘. r $’)

для (f в файлах) {if (! (f == ‘mysource.r’)) {print (paste (‘Sourcing’, f)) source (paste (d, f, sep = ”))}}

I use the above code to source all the files in a directory at start up with various utility programs I use in my interactive session with R. I am sure there are better ways but I find it useful for my work. The line that does this is as follows.

source(“~/R Code/Library/mysource.r”)

To perform an operation on a number of variables in a data frame. This is stolen from subset.data.frame.

 get.vars<-function(vars,data){ nl <- as.list(1L:ncol(data)) names(nl) <- names(data) vars <- eval(substitute(vars), nl, parent.frame()) data[,vars] #do stuff here } get.vars(c(cyl:hwy,class),mpg) 

I’ve posted this once before but I use it so much I thought I’d post it again. Its just a little function to return the names and position numbers of a data.frame. Its nothing special to be sure, but I almost never make it through a session without using it multiple times.

 ##creates an object from a data.frame listing the column names and location 

namesind=function(df){

 temp1=names(df) temp2=seq(1,length(temp1)) temp3=data.frame(temp1,temp2) names(temp3)=c("VAR","COL") return(temp3) rm(temp1,temp2,temp3) 

}

ni <- namesind

  • Возьмите сумму переменной, если комбинация значений в двух других столбцах уникальна
  • Существует pmin и pmax, каждый из которых принимает na.rm, почему нет psum?
  • Суммировать строки в data.frame или matrix
  • Сплит-кадр данных по уровням фактора и именных кадров данных по этим уровням
  • Настройка прокси для R
  • Удалите все знаки препинания, кроме апострофов в R
  • Как вычесть месяцы из даты в R?
  • Выбор только числовых столбцов из кадра данных
  • Печать новых строк с помощью print () в R
  • добавление NA, чтобы все элементы списка равны длине
  • Как вы кодируете функцию R так, чтобы она «знала», чтобы искать «данные» для переменных в других аргументах?
  • Давайте будем гением компьютера.