Уровни объединения двух столбцов
У меня есть 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
то есть Bob → 1, Tom → 2 и т.д. в обоих столбцах.
Любые идеи:)?
edit: Спасибо всем за замечательные ответы! Насколько я знаю, вы все удивительны:)
Ответы
Ответ 1
Вы хотите, чтобы факторы включали все уникальные имена из обоих столбцов.
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)
EDIT: немного лучше, если вы замените третью строку следующим образом:
mynames <- union(levels(col1), levels(col2))
Ответ 2
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)
Ответ 3
Может быть, клялся, что это не сработало, когда я писал мерзость ниже, но он делает это сейчас:
## 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
Ответ 4
В базовом пакете R. есть функция interaction()
. В пакете для survival
также есть функция strata()
.