Как пометить по комбинации доступных данных в каждой строке в R - PullRequest
0 голосов
/ 26 февраля 2019

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

Пример:

A  |  B  |  C  |  newCol
------------------------
0  |  0  |  0  |   0
1  |  0  |  0  |   1
0  |  1  |  0  |   2
0  |  0  |  1  |   3
1  |  1  |  0  |   4
0  |  1  |  1  |   5
1  |  0  |  1  |   6
1  |  1  |  1  |   7

Итак, исходя из договоренности, которая происходит между A, B и C, чтобы иметьсоответствующая метка.

Предпочтительно с использованием подхода .

Ответы [ 3 ]

0 голосов
/ 26 февраля 2019

Используя пакет , мы можем сохранить исходную сортировку (рекомендуется):

library(data.table)

setDT(df1)[,new_col:=.GRP-1, by = c("A", "B","C")]

#if you want the column as factor (one-liner, no need for previous line)
setDT(df1)[,new_col:=.GRP-1, by = c("A", "B","C")][,new_col:=as.factor(new_col)] 

Используя , мы можем сделать что-то вроде ниже:

( решение Руи реализовано в dplyr с минимальной модификацией с учетом возможности дублирования строк):

Это также сохраняет сортировку;

df1 %>% mutate(mtemp=paste0(A,B,C)) %>%  
        mutate(new_col = as.integer(factor(mtemp, levels = unique(.$mtemp)))-1) %>% 
        select(-mtemp)

Мы можем использовать фиктивную переменную для обозначения данных:

df1 %>% mutate(mtemp = paste0(A,B,C)) %>% 
        group_by(mtemp) %>% arrange(mtemp) %>% ungroup() %>%
        mutate(new_col = c(0,cumsum(lead(mtemp)[-n()] != lag(mtemp)[-1]))) %>% select(-mtemp)

# # A tibble: 8 x 5
#       A     B     C      newCol  new_col
#       <dbl> <dbl> <dbl>  <int>   <dbl>
# 1     0     0     0      0       0
# 2     0     0     0      0       0
# 3     0     0     1      3       1
# 4     0     1     0      2       2
# 5     0     1     1      5       3
# 6     1     0     0      1       4
# 7     1     1     0      4       5
# 8     1     1     1      6       6

или в отношении этой нити :

df1 %>% 
  mutate(group_id = group_indices(., paste0(A,B,C)))

Объяснение dplyr решений:

Первое решение создает фиктивную переменную, вставляя все три требуемые переменные вместе;на следующем шаге каждая группа этого фиктивного var получает уникальный идентификатор (сравните newCol с new_col).В основном, если mtemp изменяется между любыми двумя строками, мы получаем True (его числовое значение 1) как ответ нашего сравнения (lead(mtemp)...), а затем cumsum добавляет его к предыдущему сгенерированному идентификатору, который в конечном итогеприводит к различным идентификаторам для разных mtemp (комбинация A, B и C).Это решение основано на расположении фиктивной переменной и поэтому не учитывает требования сортировки.

Для другого решения просто прочитайте ?group_indices.

Данные:

df1 <- structure(list(A = c(0, 1, 0, 0, 0, 1, 0, 1), B = c(0, 0, 0, 
1, 0, 1, 1, 1), C = c(0, 0, 0, 0, 1, 0, 1, 1), newCol = c(0L, 
1L, 0L, 2L, 3L, 4L, 5L, 6L)), class = "data.frame", row.names = c(NA, 
-8L))
0 голосов
/ 26 февраля 2019

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

df$newCol <- as.numeric(as.factor(paste(df$a, df$b, df$c, sep = "")))

Если вам нужен новый столбец, точно равный 0-7 для каждогоВы можете использовать уникальную строку как две строки и unique ()

df$newCol <- as.factor(paste(df$a, df$b, df$c, sep = ""))
df$newCol <- as.numeric(factor(df$newCol, levels = unique(df$newCol)))-1

Если вам нужен этот столбец как фактор, просто сделайте это с результатом:

df$newCol <- as.factor(df$newCol)    
0 голосов
/ 26 февраля 2019

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

Сначала paste вместе значения каждой строки.

lvls <- apply(df1[-4], 1, paste, collapse = "")

Затем приведите к классу "factor" и оттуда к классу "integer".

f <- factor(lvls, levels = unique(lvls))
as.integer(f) - 1
#[1] 0 1 2 3 4 5 6

identical(df1$newCol, as.integer(f) - 1)
#[1] TRUE

Данные.

df1 <- read.table(text = "
A  |  B  |  C  |  newCol
0  |  0  |  0  |   0
1  |  0  |  0  |   1
0  |  1  |  0  |   2
0  |  0  |  1  |   3
1  |  1  |  0  |   4
0  |  1  |  1  |   5
1  |  1  |  1  |   6                  
", header = TRUE, sep = "|")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...