Гомогенизировать использование однозначных и двузначных чисел в строке - PullRequest
0 голосов
/ 29 июня 2018

У меня очень большая таблица данных, в которой (большое количество) элементы определяются строками, включая текст и числа.

library(data.table)    
dd <- data.table(x = c("A4","A4","A4","A14","A14","A14","B4","B4","B4"),y = c("A4","A14","B4","A4","A14","B4","A4","A14","B4"), z = c(1,2,3,4,5,6,7,8,9))

x   y   z
A4  A4  1
A4  A14 2
A4  B4  3
A14 A4  4
A14 A14 5
A14 B4  6
B4  A4  7
B4  A14 8
B4  B4  9

Числа могут быть однозначными или двузначными , и поэтому R будет всегда упорядочивать их в соответствии с первой цифрой в номере (A14 до A4). Mixedsort может справиться с этим. Однако, когда я изменяю длинные данные в широкие

wide <- dcast(dd, x ~ y, value.var = "z")

R снова применяет порядок согласно основному правилу порядка.

x    A14  A4  B4
A14  5    4   6
A4   2    1   3
B4   8    7   9

Мне нужно, однако, оригинальный порядок для следующих расчетов матрицы. Есть ли эффективный способ переименовать строку + однозначные в строку + двузначные (A4 -> A04) или другой подход, который я пропустил?

Ответы [ 5 ]

0 голосов
/ 29 июня 2018

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

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

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

library(gtools)
dd[,1:2] <- lapply(dd[,1:2],function(x) factor(x, mixedsort(unique(x))))

И действовать нормально:

dcast(dd, x ~ y, value.var = "z")
#      x A4 A14 B4
# 1:  A4  1   2  3
# 2: A14  4   5  6
# 3:  B4  7   8  9
0 голосов
/ 29 июня 2018

Другой, и, возможно, самый простой вариант - использовать mixedorder из пакета gtools:

wide <- dcast(dd, x ~ y, value.var = "z")[gtools::mixedorder(x)]

, что дает:

> wide
     x A14 A4 B4
1:  A4   2  1  3
2: A14   5  4  6
3:  B4   8  7  9

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

setcolorder(wide, c(1, gtools::mixedorder(names(wide)[-1]) + 1))

, который затем дает:

> wide
     x A4 A14 B4
1:  A4  1   2  3
2: A14  4   5  6
3:  B4  7   8  9
0 голосов
/ 29 июня 2018

Вы можете добавить 0 s к вашим данным с помощью

dd[nchar(x) == 2, x := paste0(substr(x, 1, 1), 0, substr(x, 2, 2))]
dd[nchar(y) == 2, y := paste0(substr(y, 1, 1), 0, substr(y, 2, 2))]

#      x   y z
# 1: A04 A04 1
# 2: A04 A14 2
# 3: A04 B04 3
# 4: A14 A04 4
# 5: A14 A14 5
# 6: A14 B04 6
# 7: B04 A04 7
# 8: B04 A14 8
# 9: B04 B04 9

Или, если вам нужно обратиться к большему количеству столбцов:

to.change <- c('x', 'y')

dd[, (to.change) := lapply(.SD, function(x) ifelse(nchar(x) > 2, x
                                                   , paste0(substr(x, 1, 1), 0, substr(x, 2, 2))))
   , .SDcols = to.change]
0 голосов
/ 29 июня 2018

Никаких дополнительных нулей в этом решении не требуется.

# Data frame
df <- data.frame(x = c("A4","A4","A4","A14","A14","A14","B4","B4","B4"),
                 y = c("A4","A14","B4","A4","A14","B4","A4","A14","B4"), 
                 z = c(1,2,3,4,5,6,7,8,9),
                 stringsAsFactors = FALSE)

# Reorder columns and rows using `mixedsort`. 
wide <- dcast(df, x ~ y,value.var   = "z") %>% 
  select(x, mixedsort(unique(df$x))) %>% 
  slice(match(x, mixedsort(unique(df$x))))

дает,

#     x A4 A14 B4
# 1  A4  1   2  3
# 2 A14  4   5  6
# 3  B4  7   8  9
0 голосов
/ 29 июня 2018

Вы можете использовать sprintf() для подготовки чисел с 0s

sprintf("%s%02.0d", "A",  1:20)
# [1] "A01" "A02" "A03" "A04" "A05" "A06" "A07" "A08" "A09" "A10" "A11" "A12" "A13" "A14" "A15" "A16" "A17" "A18" "A19" "A20"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...