Менять аргументы в tapply? - PullRequest
1 голос
/ 23 декабря 2011

У меня есть несколько групп, скажем, A, B, C, и я хочу cut другую переменную на основе этих групп, то есть каждая группа имеет определенные разрывы для одной и той же переменной.

Если бы мне нужно было вычислить среднее значение для групп, я бы использовал tapply вот так:

tapply(mydata$var,mydata$group,mean)

К сожалению, я не знаю, как это исправить для cut с изменением аргументов breaks = c (...) для разных групп.

tapply(mydata$var,mydata$group,cut)

Есть предложения? Я хотел бы сделать это с tapply, но подойдет и любое другое решение, кроме пользовательской функции.

РЕДАКТИРОВАТЬ: небольшой пример:

test <- data.frame(var=rnorm(100,0,1),
               group=c(rep("A",30),
                       rep("B",20),
                       rep("C",50)))
# for group A:
cut(test$var,breaks=c(-4,0,4))
# for group B
cut(test$var,breaks=c(-4,1,4))

и так далее ...

Ответы [ 2 ]

2 голосов
/ 23 декабря 2011

Я надену здесь свою шляпу для чтения мыслей и сделаю удар, который вам нужен, примерно так:

dat <- data.frame(x = runif(100),grp = rep(letters[1:3],length.out = 100))

mapply(cut,split(dat$x,dat$grp),list(c(-Inf,0.5,Inf),
                                     c(-Inf,0.1,0.5,0.9,Inf),
                                     c(-Inf,0.25,0.5,0.75,Inf)))

Так что это просто деление x на grp и применениеcut к каждому куску, используя разные перерывы для каждого куска.

1 голос
/ 23 декабря 2011

На самом деле R ведет себя довольно умно здесь. Я нашел решение, которое работает так, как я думал изначально. Хотя он не использует семейство apply. Каким-то образом R создает здесь целые числа вместо факторов - вот почему в этом решении нет проблем с уровнями факторов, как упоминает Джоран.

dat <- data.frame(x = rnorm(100),grp = rep(letters[1:3],length.out = 100))
ifelse(dat$grp == "a",cut(dat$x,breaks=c(-Inf,0.1,0.2,Inf)),
       ifelse(dat$grp == "b",cut(dat$x,breaks=c(-Inf,0.1,1,Inf)),
              cut(dat$x,breaks=c(-Inf,0.9,2,Inf))) )
...