Группировка / перекодирование факторов в одном и том же data.frame - PullRequest
7 голосов
/ 06 октября 2010

Допустим, у меня есть фрейм данных, подобный этому:

df <- data.frame(a=letters[1:26],1:26)

И я бы хотел "пере" перевести множители a, b и c в "a".

Как сделатьЯ так делаю?

Ответы [ 5 ]

14 голосов
/ 06 октября 2010

Одной из опций является функция recode() в пакете car:

require(car)
df <- data.frame(a=letters[1:26],1:26)
df2 <- within(df, a <- recode(a, 'c("a","b","c")="a"'))
> head(df2)
  a X1.26
1 a     1
2 a     2
3 a     3
4 d     4
5 e     5
6 f     6

Пример, где a не так прост, и мы перекодируем несколько уровней в один.

set.seed(123)
df3 <- data.frame(a = sample(letters[1:5], 100, replace = TRUE),
                  b = 1:100)
with(df3, head(a))
with(df3, table(a))

последние строки, дающие:

> with(df3, head(a))
[1] b d c e e a
Levels: a b c d e
> with(df3, table(a))
a
 a  b  c  d  e 
19 20 21 22 18

Теперь давайте объединим уровни a и e в уровень Z, используя recode()

df4 <- within(df3, a <- recode(a, 'c("a","e")="Z"'))
with(df4, head(a))
with(df4, table(a))

, что дает:

> with(df4, head(a))
[1] b d c Z Z Z
Levels: b c d Z
> with(df4, table(a))
a
 b  c  d  Z 
20 21 22 37

Делаем это без указания уровней для слияния:

## Select the levels you want (here 'a' and 'e')
lev.want <- with(df3, levels(a)[c(1,5)])
## now paste together
lev.want <- paste(lev.want, collapse = "','")
## then bolt on the extra bit
codes <- paste("c('", lev.want, "')='Z'", sep = "")
## then use within recode()
df5 <- within(df3, a <- recode(a, codes))
with(df5, table(a))

Что дает нам то же, что и df4 выше:

> with(df5, table(a))
a
 b  c  d  Z 
20 21 22 37 
13 голосов
/ 24 октября 2012

Кто-нибудь пробовал использовать этот простой метод? Это не требует специальных пакетов, просто понимание того, как R относится к факторам.

Скажем, вы хотите переименовать уровни в фактор, получить их индексы

data <- data.frame(a=letters[1:26],1:26)
lalpha <- levels(data$a)

В этом примере мы представляем, что хотим знать индекс для уровней 'e' и 'w'

lalpha <- levels(data$a)
ind <- c(which(lalpha == 'e'), which(lalpha == 'w'))

Теперь мы можем использовать этот индекс для замены уровней фактора 'a'

levels(data$a)[ind] <- 'X'

Если вы посмотрите на фактор кадра данных a, там будет X, где были e и w

Я оставляю вам попробовать результат.

3 голосов
/ 06 октября 2010

Вы можете сделать что-то вроде:

df$a[df$a %in% c("a","b","c")] <- "a"

ОБНОВЛЕНИЕ: Более сложные факторы.

Data <- data.frame(a=sample(c("Less than $50,000","$50,000-$99,999",
  "$100,000-$249,999", "$250,000-$500,000"),20,TRUE),n=1:20)
rows <- Data$a %in% c("$50,000-$99,999", "$100,000-$249,999")
Data$a[rows] <- "$250,000-$500,000"
2 голосов
/ 06 октября 2010

есть два пути. если вы не хотите сбрасывать неиспользуемые уровни, то есть «b» и «c», решение Джошуа, вероятно, будет лучшим.

если вы хотите сбросить неиспользуемые уровни, то

df$a<-factor(ifelse(df$a%in%c("a","b","c"),"a",as.character(df$a)))

или

levels(df$a)<-ifelse(levels(df$a)%in%c("a","b","c"),"a",levels(df$a))
0 голосов
/ 29 апреля 2015

Это упрощенная версия выбранного ответа:

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

df <- data.frame(a=letters[1:26],1:26)
levels(df)

> [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" 
 "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"

levels(df$a)[c(1,2)] <- "c"
summary(df$a)

> c d e f g h i j k l m n o p q r s t u v w x y z 
  3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...