R самообслуживание

В R я очень много делаю:

adataframe[adataframe$col==something]<-adataframe[adataframe$col==something)]+1

Этот путь довольно длинный и утомительный. Есть ли способ для меня
для ссылки на объект, который я пытаюсь изменить, например

adataframe[adataframe$col==something]<-$self+1 

?

Ответ 1

Попробуйте пакет data.table и его оператор :=. Это очень быстро и очень коротко.

DT[col1==something, col2:=col3+1]

Первая часть col1==something - это подмножество. Вы можете поместить что-нибудь здесь и использовать имена столбцов, как если бы они были переменными; то есть нет необходимости использовать $. Затем вторая часть col2:=col3+1 назначает RHS для LHS внутри этого подмножества, где имена столбцов могут быть назначены так, как если бы они были переменными. := - присвоение по ссылке. Никаких копий какого-либо объекта не выполняется, поэтому выполняется быстрее, чем <-, =, within и transform.

Кроме того, в ближайшее время, чтобы быть реализованным в v1.8.1, одна конечная цель синтаксиса j, позволяющая := в j как это объединить его с by, см. вопрос: когда следует использовать оператор := в data.table.

UDPDATE: это действительно было выпущено (:= по группе) в июле 2012 года.

Ответ 2

Вы должны уделять больше внимания Gabor Grothendeick (и не только в этом случае.) Приведенная функция inc в блоге Matt Asher делает все, что вы просите:

(И очевидное расширение работает также.)

add <- function(x, inc=1) {
   eval.parent(substitute(x <- x + inc))
 }
# Testing the `inc` function behavior

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

transfn <- function(x, func="+", inc=1) {
   eval.parent(substitute(x <- do.call(func, list(x , inc)))) }

(Виновный вход: это как-то "чувствует себя не так" от традиционной перспективы R для возврата значений для назначения.) Более раннее тестирование функции inc ниже:

> df <- data.frame(a1 =1:10, a2=21:30, b=1:2)
> inc <- function(x) {
+   eval.parent(substitute(x <- x + 1))
+ }
> inc(df$a1)  # works on whole columns
> df
   a1 a2 b
1   2 21 1
2   3 22 2
3   4 23 1
4   5 24 2
5   6 25 1
6   7 26 2
7   8 27 1
8   9 28 2
9  10 29 1
10 11 30 2
> inc(df$a1[df$a1>5]) # testing on a restricted range of one column
> df
   a1 a2 b
1   2 21 1
2   3 22 2
3   4 23 1
4   5 24 2
5   7 25 1
6   8 26 2
7   9 27 1
8  10 28 2
9  11 29 1
10 12 30 2

> inc(df[ df$a1>5, ])  #testing on a range of rows for all columns being transformed
> df
   a1 a2 b
1   2 21 1
2   3 22 2
3   4 23 1
4   5 24 2
5   8 26 2
6   9 27 3
7  10 28 2
8  11 29 3
9  12 30 2
10 13 31 3
# and even in selected rows and grepped names of columns meeting a criterion
> inc(df[ df$a1 <= 3, grep("a", names(df)) ])
> df
   a1 a2 b
1   3 22 1
2   4 23 2
3   4 23 1
4   5 24 2
5   8 26 2
6   9 27 3
7  10 28 2
8  11 29 3
9  12 30 2
10 13 31 3

Ответ 3

Вот что вы можете сделать. Скажем, у вас есть dataframe

df = data.frame(x = 1:10, y = rnorm(10))

И вы хотите увеличить все y на 1. Вы можете сделать это легко, используя transform

df = transform(df, y = y + 1)

Ответ 4

Я был бы частичным (предположительно, подмножество находится в строках)

ridx <- adataframe$col==something
adataframe[ridx,] <- adataframe[ridx,] + 1

который не полагается на какой-либо причудливый/хрупкий синтаксический анализ, достаточно выразителен в отношении выполняемой операции и не слишком подробен. Также имеет тенденцию ломать линии в хорошие человеко-синтаксические единицы, и есть что-то привлекательное в использовании стандартных идиом - лексика и особенности языка Я уже достаточно велики для моего вкуса.