В R транспонировать и объединять несколько фреймов данных с отсутствующими данными и пустыми именами столбцов / переименовывать расплавленные столбцы до dcast

Я искал и нашел много решений, которые были близки, но в итоге так и не сработали. Это, наверное, что-то очень простое, для тех, кто имеет опыт...

Вот фрагмент моих данных. Это было создано автоматически из импорта JSON пакетом jsonlite. Данные очень хорошо структурированы, но я все же беспомощен. Обновление 2: я добавил соответствующие данные ниже

    structure(list(rightsize = c(42L, 50L, 52L, 49L, 41L, 41L, 41L, 
41L, 41L, 45L, 47L, 42L, 45L, 46L, 42L, 44L, 44L, 37L, 44L, 41L
), hitlen = c("", "", "", "", "", "", "", "", "", "", "", "", 
"", "", "", "", "", "", "", ""), linegroup = c("_", "_", "_", 
"_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", "_", 
"_", "_", "_", "_"), leftsize = c(46L, 43L, 43L, 37L, 49L, 43L, 
43L, 45L, 45L, 43L, 44L, 46L, 45L, 46L, 44L, 43L, 54L, 45L, 51L, 
47L), leftspace = c("        ", "           ", "           ", 
"                 ", "     ", "           ", "           ", "         ", 
"         ", "           ", "          ", "        ", "         ", 
"        ", "          ", "           ", "", "         ", "   ", 
"       "), Left = list(structure(list(class = c("", "coll", 
""), str = c("patients with ", "chronic", " obstructive pulmonary"
)), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = c("", "coll", ""), str = c("respect to ", 
"chronic", " obstructive pulmonary")), .Names = c("class", "str"
), class = "data.frame", row.names = c(NA, 3L)), structure(list(
    class = c("", "coll", ""), str = c("While there is no cure for this ", 
    "chronic", " ")), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = c("", "strc", "", "coll", ""), str = c(".", 
"</p><p>", "When patients with ", "chronic", " liver")), .Names = c("class", 
"str"), class = "data.frame", row.names = c(NA, 5L)), structure(list(
    class = c("", "coll", ""), str = c("bronchitis , and ", "chronic", 
    " obstructive pulmonary")), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = c("", "coll", ""), str = c("offers the possibility that ", 
"chronic", " lung")), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = c("", "coll", ""), str = c(" , such as ", 
"chronic", " obstructive pulmonary")), .Names = c("class", "str"
), class = "data.frame", row.names = c(NA, 3L)), structure(list(
    class = c("", "coll", ""), str = c("always as clear in other ", 
    "chronic", " incurable")), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = c("", "coll", ""), str = c("may have the potential to prevent ", 
"chronic", " ")), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = c("", "coll", ""), str = c(" half the estimated cost of all ", 
"chronic", " ")), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = c("", "coll", ""), str = c("is consistent with the tact that ", 
"chronic", " ")), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = c("", "coll", ""), str = c("used to treat ", 
"chronic", " obstructive pulmonary")), .Names = c("class", "str"
), class = "data.frame", row.names = c(NA, 3L)), structure(list(
    class = c("", "coll", ""), str = c("ingredient for dietary therapy of ", 
    "chronic", " ")), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = c("", "coll", ""), str = c("patients with ", 
"chronic", " obstructive pulmonary")), .Names = c("class", "str"
), class = "data.frame", row.names = c(NA, 3L)), structure(list(
    class = c("", "coll", ""), str = c("greater for ", "chronic", 
    " obstructive pulmonary")), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = c("", "coll", ""), str = c(" departments , with schemes for ", 
"chronic", " ")), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = c("", "coll", ""), str = c("postponement of death by means of managing ", 
"chronic", " ")), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = c("", "coll", ""), str = c("certainly be ", 
"chronic", " obstructive pulmonary")), .Names = c("class", "str"
), class = "data.frame", row.names = c(NA, 3L)), structure(list(
    class = c("", "coll", ""), str = c("cardiovascular disease , cancer , other ", 
    "chronic", " ")), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = c("", "coll", ""), str = c("terminal illnesses are converted to ", 
"chronic", " ")), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L))), Right = list(structure(list(class = "", str = " who may be at risk of developing steroid"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " - plausibly related to exposure to environmental"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " , it can be treated , Black says . Antidepressants"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " ask what they can do to improve their condition"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " [ COPD ] ) was 15 % ( estimated within "), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " is part of the continuum of development"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " ( 70 , 71 ) and sleep apnea . Elevation"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " . Patients with heart failure highlight"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " other than heart disease , and helps us"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " in this country . Furthermore , the portion"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " are multigenic and multifactorial . Therefore"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " . Nasal corticosteroids are increasingly"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " such as diabetes mellitus or hyperlipidemia"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " ( COPD ) concluded exercise relieves dyspnea"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " than for any other disease. 5 The number"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " management in patients with COPD receiving"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " and disability is costly , and it is bound"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = c("", "strc", ""), str = c(" .", "</p><p>", "Much rarer condition , but people"
    )), .Names = c("class", "str"), class = "data.frame", row.names = c(NA, 
3L)), structure(list(class = "", str = " , and in fact those rates have been rising"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "", str = " . The panel 's report is negative about"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L)), Kwic = list(structure(list(
    class = "col0 coll", str = " disease"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = " disease"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = "disease"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = " disease"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = " disease"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = " disease"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = " disease"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = " diseases"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = "diseases"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = "diseases"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = "diseases"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = " disease"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = "diseases"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = " disease"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = " disease"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = "disease"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = "disease"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = " disease"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = "diseases"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L), structure(list(
    class = "col0 coll", str = "diseases"), .Names = c("class", 
"str"), class = "data.frame", row.names = 1L)), toknum = c(580661252L, 
585871494L, 572902309L, 596182644L, 611091300L, 604962106L, 605346237L, 
585102838L, 575701411L, 616556239L, 548908661L, 604489309L, 548601059L, 
617460845L, 585870185L, 591049175L, 581965276L, 592616458L, 592591831L, 
599295354L), rightspace = c("          ", "  ", "", "   ", "           ", 
"           ", "           ", "           ", "           ", "       ", 
"     ", "          ", "       ", "      ", "          ", "        ", 
"        ", "               ", "        ", "           "), Tbl_refs = list(
    "11.99.0023.006", "11.99.0031.001", "11.99.0012.004", "11.99.0046.013", 
    "11.99.0069.003", "11.99.0059.007", "11.99.0060.003", "11.99.0030.001", 
    "11.99.0016.007", "11.99.0077.021", "11.01.0003.015", "11.99.0059.003", 
    "11.01.0003.006", "11.99.0078.034", "11.99.0031.001", "11.99.0038.005", 
    "11.99.0025.005", "11.99.0040.006", "11.99.0040.006", "11.99.0051.011"), 
    ref = c("11.99.0023.006", "11.99.0031.001", "11.99.0012.004", 
    "11.99.0046.013", "11.99.0069.003", "11.99.0059.007", "11.99.0060.003", 
    "11.99.0030.001", "11.99.0016.007", "11.99.0077.021", "11.01.0003.015", 
    "11.99.0059.003", "11.01.0003.006", "11.99.0078.034", "11.99.0031.001", 
    "11.99.0038.005", "11.99.0025.005", "11.99.0040.006", "11.99.0040.006", 
    "11.99.0051.011")), .Names = c("rightsize", "hitlen", "linegroup", 
"leftsize", "leftspace", "Left", "Right", "Kwic", "toknum", "rightspace", 
"Tbl_refs", "ref"), class = "data.frame", row.names = c(NA, 20L
))

Что мне нужно сделать, это 1) транспонировать эти 4 кадра данных и назначить значения в "классе" в качестве заголовков столбцов. Обратите внимание, #1, количество столбцов может отличаться. Также обратите внимание (#2), что некоторые имена столбцов будут "". Как таковое, замечательное решение в данном случае приводит к кадрам данных, в которых некоторые заголовки столбцов заполнены мусором, что делает следующий шаг (объединение данных) невозможным, например,

  1. ""
  2. STRC
  3. структура ("Когда пациенты с", класс = "AsIs")
  4. Coll
  5. структура ("печень", класс = "AsIs").

(Похоже, что заголовки "мусорной заливки" - это те, которые были "", кроме первой.)

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

Обновление: я продолжал экспериментировать с расплавлением / отливкой. Следующее приносит очень близко к приемлемым, окончательным решениям:

require(reshape2)
docx <- melt(documentdata$Left, id.vars = c("class"))
docx <- dcast(docx, L1 + variable ~ class, fun.aggregate=list)

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

    L1  variable    Var.3   coll    strc
1    1  str patients with ,  obstructive pulmonary  chronic  
2    2  str respect to ,  obstructive pulmonary chronic  
3    3  str While there is no cure for this ,   chronic  
4    4  str ., When patients with ,  liver  chronic </p><p>
5    5  str bronchitis , and ,  obstructive pulmonary   chronic  

Ключом "class" в данных og является переменная "coll", в которой всегда есть хотя бы один пробел до и один пробел после. Одним из решений может быть создание имен "pre-coll" и "post-coll" до dcast?

Обновление № 3: вот одно из возможных, хотя и некрасивых решений. Какие-нибудь "более чистые" варианты?

require(reshape2)
docx <- melt(documentdata$Left, id.vars = c("class"))
pre <- which(docx$class %in% c("coll")) - 1
post <- which(docx$class %in% c("coll")) + 1
docx$class[pre] = "l.pre"
docx$class[post] = "l.post"
docx <- dcast(docx, L1 + variable ~ class, fun.aggregate=list)
docx.left <- docx[, c("l.pre", "coll", "l.post")]

Заранее спасибо за помощь.

1 ответ

Решение

Давайте сделаем это с dplyr:

library(dplyr)
documentdata$Left %>% do.call(rbind, .) %>%
                      do(data.frame(pre = .[["str"]][which(.[["class"]]=="coll")-1],
                                    coll = .[["str"]][which(.[["class"]]=="coll")], 
                                    post = .[["str"]][which(.[["class"]]=="coll")+1]))

                                           pre    coll                   post
1                               patients with  chronic  obstructive pulmonary
2                                  respect to  chronic  obstructive pulmonary
3             While there is no cure for this  chronic                       
4                          When patients with  chronic                  liver
5                            bronchitis , and  chronic  obstructive pulmonary
6                 offers the possibility that  chronic                   lung
....
18                               certainly be  chronic  obstructive pulmonary
19    cardiovascular disease , cancer , other  chronic                       
20        terminal illnesses are converted to  chronic  

РЕДАКТИРОВАТЬ: объяснение:dplyr имеет странный синтаксис. См. Виньетка dplyr или шпаргалку для обработки данных. %>% это труба из magrittr пакет и просто помещает вывод всего слева от канала в качестве первого аргумента, если функция направо:

5 %>% c(1)
#same as
c(5, 1) 

Вы можете использовать . представлять материал слева, если вы хотите использовать его в другом месте. Вы можете подмножество . если вам нравится (например, .[["str"]]):

5 %>% c(1, .)
#same as
c(1, 5)

do позволяет нам делать любые вычисления, не беспокоясь о стандарте dplyr глаголы - это обертка. Увидеть ?do,

Таким образом, ответ принимает documentdata$Leftтрубит do.call(rbind, .) который сворачивает список (пока это так же, как do.call(rbind, documentdata$Left)). Мы передаем это do который создает новый фрейм данных с соответствующими столбцами, выбранными из .,

Другие вопросы по тегам