Уровни объединения двух столбцов - PullRequest
12 голосов
/ 31 января 2011

У меня есть 2 столбца данных с одинаковым типом данных (строки).

Я хочу объединить уровни столбцов.то есть.у нас есть:

col1   col2
Bob    John
Tom    Bob
Frank  Jane
Jim    Bob
Tom    Bob
...    ... (and so on)

теперь col1 имеет 4 уровня (Боб, Том Фрэнк, Джим), а col2 имеет 3 уровня (Джон, Джейн, Боб)

Но я хочу, чтобы оба столбца имеливсе уровни факторов (Боб, Том, Фрэнк, Джим, Джейн, Джон), чтобы впоследствии заменить каждое из «имен» уникальным идентификатором, так что конечный результат будет:

col1   col2
1      5
2      1
3      6
4      1
2      1

то есть Боб -> 1, Том -> 2 и т. д. в обеих колонках.

Любые идеи :)?

edit: Спасибо всем за замечательные ответы!Насколько я знаю, вы все потрясающие:)

Ответы [ 3 ]

11 голосов
/ 31 января 2011
x <- structure(list(col1 = structure(c(1L, 4L, 2L, 3L, 4L), .Label = c("Bob", "Frank", "Jim", "Tom"), class = "factor"), col2 = structure(c(3L, 1L, 2L, 1L, 1L), .Label = c("Bob", "Jane", "John"), class = "factor")), .Names = c("col1", "col2"), class = "data.frame", row.names = c(NA, -5L))

Создайте простое объединение имен факторов:

both <- union(levels(x$col1), levels(x$col2))

и добавьте два фактора:

x$col1 <- factor(x$col1, levels=both)
x$col2 <- factor(x$col2, levels=both)

После редактирования: добавлен пример создания числовых значений из факторов

Вы можете просто преобразовать уровни факторов в числовые значения, например:

as.numeric(x$col1)

Или более простое, более приятное решение, основанное на подсказке @Gavin Simpson нижеза один шаг:

data.matrix(x)
5 голосов
/ 31 января 2011

Вы хотите, чтобы факторы включали все уникальные имена из обоих столбцов.

col1 <- factor(c("Bob", "Tom", "Frank", "Jim", "Tom"))
col2 <- factor(c("John", "Bob", "Jane", "Bob", "Bob"))
mynames <- unique(c(levels(col1), levels(col2)))
fcol1 <- factor(col1, levels = mynames)
fcol2 <- factor(col2, levels = mynames)

РЕДАКТИРОВАТЬ: немного лучше, если вы замените третью строку следующим:

mynames <- union(levels(col1), levels(col2))
2 голосов
/ 31 января 2011

Мог бы поклясться, что это не сработало, когда я писал мерзость ниже, но теперь это так:

## self contained example:
txt <- "col1   col2
Bob    John
Tom    Bob
Frank  Jane
Jim    Bob
Tom    Bob"
dat <- read.table(textConnection(txt), header = TRUE)

Просто вычислите уникальный набор уровней и приведите каждый colX к коэффициенту:

> dat3 <- dat
> lev <- as.character(unique(unlist(sapply(dat, levels))))
> dat3 <- within(dat3, col1 <- factor(col1, levels = lev))
> dat3 <- within(dat3, col2 <- factor(col2, levels = lev))
> str(dat3)
'data.frame':   5 obs. of  2 variables:
 $ col1: Factor w/ 6 levels "Bob","Tom","Frank",..: 1 2 3 4 2
 $ col2: Factor w/ 6 levels "Bob","Tom","Frank",..: 5 1 6 1 1
> data.matrix(dat3)
     col1 col2
[1,]    1    5
[2,]    2    1
[3,]    3    6
[4,]    4    1
[5,]    2    1

[ Оригинал: , чтобы показать, насколько глупо и запутанно можно писать R-код, если очень стараешься!] Не уверен, что это особенно элегантно (и это не так),но ...

Сначала мы выводим данные:

tmp <- unlist(dat)

, затем вычисляем уникальные уровни

lev <- as.character(unique(tmp))

, а затем реструктурируем tmp (сверху) назад.в те же измерения, что и исходные данные, преобразуйте в data.frame (сохраняя строки), примените к этому фрейму данных, создав коэффициент с вычисленными выше уровнями lev и, наконец, приведите к фрейму данных.

dat2 <- data.frame(lapply(data.frame(matrix(tmp, ncol = ncol(dat)), 
                                     stringsAsFactors = FALSE), 
                          FUN = factor, levels = lev))

Что дает:

> dat2
     X1   X2
1   Bob John
2   Tom  Bob
3 Frank Jane
4   Jim  Bob
5   Tom  Bob
> sapply(dat2, levels)
     X1      X2     
[1,] "Bob"   "Bob"  
[2,] "Tom"   "Tom"  
[3,] "Frank" "Frank"
[4,] "Jim"   "Jim"  
[5,] "John"  "John" 
[6,] "Jane"  "Jane" 
> data.matrix(dat2)
     X1 X2
[1,]  1  5
[2,]  2  1
[3,]  3  6
[4,]  4  1
[5,]  2  1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...