Разбить каждую строку в столбце с несколькими уникальными словами на несколько столбцов - PullRequest
1 голос
/ 18 апреля 2020

Я хотел бы создать функцию для создания, которая проверяет уникальные слова в одной строке, спускаясь вниз по столбцу и создавая фиктивные столбцы на основе этого. Например:

ID Letters
1  A, B, C
2  C, D
3  A
4  B, D
5  Z
6  A

Ожидаемый результат будет:

ID Letters  Letter_A Letter_B Letter_C Letter_D Letter_Z
1  A, B, C   1          1        1        0       0
2  C, D      0          0        1        1       0
3  A         1          0        0        0       0
4  B, D      0          1        0        1       0
5  Z         0          0        0        0       1
6  A         1          0        0        0       0

Я нашел этот блок кода

uniq <- unique(unlist(strsplit(as.character(df$values),', ')))
m <- matrix(0, nrow(df), length(uniq), dimnames = list(NULL, paste0("Letter_", uniq)))

for (i in seq_along(df$values)) {
  k <- match(df$values[i], uniq, 0)
  m[i,k] <- 1
}

Где uniq создаст новый удерживайте каждое уникальное слово через запятую и создайте новый столбец Letter_A et c. Однако forl oop будет проверять только первую букву в столбце. Таким образом, текущий результат выглядит так, когда другие буквы не меняются на 1

ID Letters  Letter_A Letter_B Letter_C Letter_D Letter_Z
1  A, B, C   1          0        0        0       0
2  C, D      0          0        1        0       0
3  A         1          0        0        0       0
4  B, D      0          1        0        0       0
5  Z         0          0        0        0       1
6  A         1          0        0        0       0

Ответы [ 4 ]

1 голос
/ 20 апреля 2020

Опция, использующая stats::xtabs и DF, является решением Коула:

l <- strsplit(DF$Letters, ", ") 
tab <- data.frame(ID=rep(seq_along(l), lengths(l)), Letters=unlist(l), V=1L)
cbind(DF, as.data.frame.matrix(xtabs(V ~ ID + Letters, tab)))

вывод:

  ID Letters A B C D Z
1  1 A, B, C 1 1 1 0 0
2  2    C, D 0 0 1 1 0
3  3       A 1 0 0 0 0
4  4    B, D 0 1 0 1 0
5  5       Z 0 0 0 0 1
6  6       A 1 0 0 0 0
1 голос
/ 18 апреля 2020

Код:

library(data.table)
setDT(df)
dcast(data = df[, strsplit(Letters, split = ","), by = .(ID, Letters)][, V1 := trimws(V1)][],
      formula = ID + Letters ~ V1, 
      fun.aggregate = length, 
      value.var = "V1")
#    ID Letters A B C D Z
# 1:  1 A, B, C 1 1 1 0 0
# 2:  2    C, D 0 0 1 1 0
# 3:  3       A 1 0 0 0 0
# 4:  4    B, D 0 1 0 1 0
# 5:  5       Z 0 0 0 0 1
# 6:  6       A 1 0 0 0 0

Данные:

df <- read.table(text='ID Letters
1  "A, B, C"
                 2  "C, D"
                 3  "A"
                 4  "B, D"
                 5  "Z"
                 6  "A"', header = TRUE, stringsAsFactors = FALSE)
1 голос
/ 18 апреля 2020

Вы можете использовать функцию mtabulate из библиотеки qdapTools.

library(qdapTools)
library(dplyr)

x <- "
ID Letters
1  'A, B, C'
2  'C, D'
3  A
4  'B, D'
5  Z
6  A
"

df <- read.table(text = x, header = TRUE, stringsAsFactors = FALSE)

encoded_df <- cbind(df, mtabulate(strsplit(df$Letters, ", "))) %>% 
              rename_at(vars(!colnames(df)), ~paste0("Letter_", .))

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

1 голос
/ 18 апреля 2020

Вот один из способов сделать это:

DF = data.frame(ID = seq_len(6L),
                Letters = c("A, B, C", "C, D", "A", "B, D", "Z", "A"))

spl_letters = strsplit(as.character(DF[["Letters"]]), ", ", fixed = TRUE)
uniq = unique(unlist(spl_letters), use.names = FALSE)

data.frame(DF,
           setNames(data.frame(t(vapply(spl_letters, function(x) +(uniq %in% x), seq_along(uniq)))), paste0("Letter_", uniq))
)

  ID Letters Letter_A Letter_B Letter_C Letter_D Letter_Z
1  1 A, B, C        1        1        1        0        0
2  2    C, D        0        0        1        1        0
3  3       A        1        0        0        0        0
4  4    B, D        0        1        0        1        0
5  5       Z        0        0        0        0        1
6  6       A        1        0        0        0        0

По сути, for l oop был изменен на vapply, и вместо unlist был сохранен исходный результат strsplit. чтобы соответствовать тому, что было uniq.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...