Обработка данных в R: подмножество и упорядочивание векторов разной длины

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

У меня есть данные, которые поступают из электронной таблицы в следующем виде:

Данные:

1   GOEK, WOWP, PEOL, WJRN, KENC, QPOE, JFPG, PWKR, PWEOR, JFOKE, POQK, LSPF, PEKF,PFOW, VCNS, ALAO, LFOD
2   KFDL, LFOD, WOWP, PWEO, PWEOR, PRCP, ALPQ, JFOKE, ALLF, VCNS CNIR,
3   KJTJ, FKOF, VCNS, FLEP
4   FKKF, EPTR
5   QPOE,  PEOL, WJRN, VCNS, PEKF, PFPW

И эти данные связаны со следующим ключом:

Ключ:

Items   A   B   C
ALAO    NA  0.12246503  0.137902549
ALLF    0.016262491 0.557522799 0.622560763
ALPQ    0.409770566 0.770904525 NA
CNIR    NA  0.38075281  0.698236443
EPTR    0.718354484 0.290028597 0.525661861
FKKF    0.801489091 0.878405308 0.645004844
FKOF    0.643251028 0.131643544 NA
FLEP    0.018262707 0.211220859 0.457302727
GOEK    0.902121539 NA  NA
JFOKE   0.808410498 0.301443669 0.575188395
JFPG    NA  NA  0.343824191
KENC    0.882285296 0.372821865 0.593742731
KFDL    0.077569421 0.076497291 NA
KJTJ    0.249613609     0.227241864 NA
LFOD    NA  0.000343115 0.329546051
LSPF    0.088451014 0.65148309  0.267490643
PEKF    0.645309773 NA  0.116601451
PEOL    0.626916187 0.093812247 0.152577881
PFOW    0.86690534  0.596673645 NA
PFPW    NA  0.018869604 NA
POQK    0.683221579 NA  0.472456955
PRCP    0.486488748 0.860947689 0.097916066
PWEO    0.665854791 0.814111848 0.026085774
PWEOR   0.611034332 0.17254104  0.212386401
PWKR    NA  NA  0.357298987
QPOE    0.815885005 0.083834541 NA
VCNS    0.394817612 0.250760686 0.419539549
WJRN    0.403002388 0.705142265 0.768961818
WOWP    0.794250738 NA  0.967405211

Вот общий подход:

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

Отфильтруйте данные по трем категориям (A, B или C) в зависимости от значения в строке, с которой они связаны. Например, для 5-й строки данных у нас есть значения: QPOE, PEOL, WJRN, VCNS, PEKF, PFPW. Глядя на ключ, мы можем превратить его в три подкатегории в зависимости от того, что содержится в A, B или C. Это зависит от того, есть ли NA в этой строке или нет:

A QPOE PEOL WJRN VCNS PEKF B QPOE PEOL WJRN VCNS PFPW C PEOL WJRN VCNS PEKF

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

A 0.815885005 0.626916187 0.403002388 0.394817612 0.645309773 B 0.083834541 0.093812247 0.705142265 0.250760686 0.018869604 C 0.152577881 0.768961818 0.419539549 0.116601451

Итак, у нас есть что-то вроде хеш-таблицы... вроде того. Теперь я хочу сохранить эти значения в одной таблице. По сути, в окончательной форме это будет выглядеть примерно так (показано только для строки 5 data):

Cat A Item  A Value B Item  B Value C Item  C Value
5   QPOE    0.815885005 QPOE    0.083834541 PEOL    0.152577881
5   PEOL    0.626916187 PEOL    0.093812247 WJRN    0.768961818
5   WJRN    0.403002388 WJRN    0.705142265 VCNS    0.419539549
5   VCNS    0.394817612 VCNS    0.250760686 PEKF    0.116601451
5   PEKF    0.645309773 PFPW    0.018869604 NA  NA

На самом деле у меня 400 строк «Кошка» в данных, а не только 5.

Является ли это лучшим способом хранения данных для удобства? Будет ли предпочтительным вложенный список?

  1. Cat Row 1
    • A Items
      • Values
    • B Items
      • Values
    • C Items
      • Values
  2. Кошачий ряд 2...

Я просто не решаюсь создавать фреймы данных для этих данных, потому что длина строк в моих исходных данных при разделении на A, B и C очень сильно различается. Самые короткие строки должны быть иметь NA для заполнения до длины самых длинных, чтобы поместиться во фрейме данных. Что-то в этом мне просто неудобно.

Я всегда могу найти функции, используемые в ответе, и понять это, поэтому подробное объяснение не требуется, если только вы не чувствуете себя особенно щедрым! Спасибо за ваше время.


person syntonicC    schedule 16.04.2014    source источник


Ответы (1)


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

Начните с ваших данных:

d <- c("GOEK, WOWP, PEOL, WJRN, KENC, QPOE, JFPG, PWKR, PWEOR, JFOKE, POQK, LSPF, PEKF,PFOW, VCNS, ALAO, LFOD",
"KFDL, LFOD, WOWP, PWEO, PWEOR, PRCP, ALPQ, JFOKE, ALLF, VCNS CNIR",
"KJTJ, FKOF, VCNS, FLEP", "FKKF, EPTR", "QPOE,  PEOL, WJRN, VCNS, PEKF, PFPW"    )

key <- structure(list(Items = c("ALAO", "ALLF", "ALPQ", "CNIR", "EPTR",
"FKKF", "FKOF", "FLEP", "GOEK", "JFOKE", "JFPG", "KENC", "KFDL",
"KJTJ", "LFOD", "LSPF", "PEKF", "PEOL", "PFOW", "PFPW", "POQK",
"PRCP", "PWEO", "PWEOR", "PWKR", "QPOE", "VCNS", "WJRN", "WOWP"
), A = c(NA, 0.016262491, 0.409770566, NA, 0.718354484, 0.801489091,
0.643251028, 0.018262707, 0.902121539, 0.808410498, NA, 0.882285296,
0.077569421, 0.249613609, NA, 0.088451014, 0.645309773, 0.626916187,
0.86690534, NA, 0.683221579, 0.486488748, 0.665854791, 0.611034332,
NA, 0.815885005, 0.394817612, 0.403002388, 0.794250738), B = c(0.12246503,
0.557522799, 0.770904525, 0.38075281, 0.290028597, 0.878405308,
0.131643544, 0.211220859, NA, 0.301443669, NA, 0.372821865, 0.076497291,
0.227241864, 0.000343115, 0.65148309, NA, 0.093812247, 0.596673645,
0.018869604, NA, 0.860947689, 0.814111848, 0.17254104, NA, 0.083834541,
0.250760686, 0.705142265, NA), C = c(0.137902549, 0.622560763,
NA, 0.698236443, 0.525661861, 0.645004844, NA, 0.457302727, NA,
0.575188395, 0.343824191, 0.593742731, NA, NA, 0.329546051, 0.267490643,
0.116601451, 0.152577881, NA, NA, 0.472456955, 0.097916066, 0.026085774,
0.212386401, 0.357298987, NA, 0.419539549, 0.768961818, 0.967405211
)), .Names = c("Items", "A", "B", "C"), class = "data.frame", row.names = c(NA, -29L))

#split it up as you suggest
d <- strsplit(d,",")
d <- lapply(d, gsub, pattern=" ", replacement="") #Get rid of trailing spaces

#Convert key to a long data.frame with no NAs
library(reshape2)   
key <- melt(key)
names(key)[2] <- "letter" #You might have better name for this
key <- key[complete.cases(key),] 

#Extract subsets for each row of data
lapply(d, function(x)key[key$Items %in% x,])
person Miff    schedule 16.04.2014
comment
Обратите внимание, что KJTJ в данных имеет только два из трех значений — вы должны проверить, почему это так. - person Miff; 16.04.2014
comment
Это сработало красиво, спасибо! Я бы никогда не подумал сделать это таким образом. Формат списка, который вы использовали, идеален и лучше, чем то, что я предложил. Кроме того, я добавил NA для KJTJ - думаю, я как-то потерял его, когда редактировал свой пост. - person syntonicC; 16.04.2014