Ответы, опубликованные до сих пор, предлагают решения с использованием регулярных выражений.
В качестве альтернативы, могут быть рассмотрены позиции столбцов. Как указывал ОП
blockquote>
- ColA имеет строку перед 1-й запятой;
- ColB имеет все между 1 и 2 запятой;
- У ColD есть строка после последней запятой;
- ColC имеет строку в средней части (она может содержать дополнительные запятые).
Идея состоит в том, чтобы прочитать файл, используя
fread()
сsep = ","
, как обычно, что приводит к смещению набора данных. После преобразования в длинный формат можно определить первый, второй и последний столбцы, а также промежуточные столбцы на строку . Этим записям можно присвоить имя соответствующего столбца. Во время окончательного преобразования в широкоформатный формат промежуточные столбцы свернуты вColC
.library(data.table) # read file DT <- fread(" 1,10,some text... some text,,20190801 2,22,some text... , some text,,20190801 3,30,some text... ,, some text,,20170601" , sep = "," , fill = TRUE , header = FALSE , strip.white = FALSE)
Обратите внимание, что образец набора данных был изменен путем вставки дополнительной запятой, чтобы иметь более реалистичный контрольный пример.
Результатом операции чтения является выровненный и рваный набор данных:
DT
blockquote>V1 V2 V3 V4 V5 V6 V7 1: 1 10 some text... some text 20190801 NA NA 2: 2 22 some text... some text 20190801 NA 3: 3 30 some text... some text NA 20170601
cols <- c("ColA", "ColB", "ColC", "ColD") # reshape from wide to long format long <- melt(DT[, rn := .I], "rn", na.rm = TRUE) # create lookup table to rename column names lut <- long[, .(variable, col = rep(cols, c(1L, 1L, .N - 3, 1L))), by = rn] # rename columns by an update join long[lut, on = .(rn, variable), variable := col][] # reshape and collapse dcast(long, rn ~ variable, paste, collapse = ",")
blockquote>ColA ColB ColC ColD 1: 1 10 some text... some text, 20190801 2: 2 22 some text... , some text, 20190801 3: 3 30 some text... ,, some text 20170601
Подход можно лучше объяснить, если мы посмотрим на промежуточные результаты.
После
melt()
,long
равноblockquote>rn variable value 1: 1 V1 1 2: 2 V1 2 3: 3 V1 3 4: 1 V2 10 5: 2 V2 22 6: 3 V2 30 7: 1 V3 some text... some text 8: 2 V3 some text... 9: 3 V3 some text... 10: 1 V4 11: 2 V4 some text 12: 3 V4 13: 1 V5 20190801 14: 2 V5 15: 3 V5 some text 16: 2 V6 20190801 17: 3 V7 20170601
Из этого создается таблица соответствия
lut
blockquote>rn variable col 1: 1 V1 ColA 2: 1 V2 ColB 3: 1 V3 ColC 4: 1 V4 ColC 5: 1 V5 ColD 6: 2 V1 ColA 7: 2 V2 ColB 8: 2 V3 ColC 9: 2 V4 ColC 10: 2 V5 ColC 11: 2 V6 ColD 12: 3 V1 ColA 13: 3 V2 ColB 14: 3 V3 ColC 15: 3 V4 ColC 16: 3 V5 ColC 17: 3 V7 ColD
После присоединения обновления и перед преобразованием обратно в широкоформатный формат
long
выглядит какblockquote>rn variable value 1: 1 ColA 1 2: 2 ColA 2 3: 3 ColA 3 4: 1 ColB 10 5: 2 ColB 22 6: 3 ColB 30 7: 1 ColC some text... some text 8: 2 ColC some text... 9: 3 ColC some text... 10: 1 ColC 11: 2 ColC some text 12: 3 ColC 13: 1 ColD 20190801 14: 2 ColC 15: 3 ColC some text 16: 2 ColD 20190801 17: 3 ColD 20170601
Теперь элементы данных выровнены по соответствующим именам столбцов. .
Похоже, вы пытаетесь выполнить эквивалент условия "WHERE ... IN". Ознакомьтесь с Как писать запросы в стиле «WHERE IN» с использованием LINQ to Entities , чтобы увидеть пример того, как выполнять этот тип запроса с LINQ to Entities.
Кроме того, я думаю, что сообщение об ошибке особенно бесполезно в данном случае, поскольку за .Contains
не ставятся круглые скобки, компилятор распознает весь предикат как лямбда-выражение.