2013-05-22 1 views
0

Я по-прежнему новичок в R и, возможно, полностью перепутал концепцию фреймов данных.Создание фрейма данных из файла CSV со встроенными списками

Но у меня есть файл CSV в следующем формате:

ID;Year;Title;Authors;Keywords; 

Где авторы и ключевые слова должны быть списком строк. Например.

1; 2013; К Dynamic Non-навязчивой мониторинга здоровья на основе SOA и Cloud; Мохаммед Serhani, Абдельгани Benharret, Erlabi Badidi; E-здоровье, заболевания, мониторинг, профилактика, SOA, Облако, платформа, м- технологий;

Есть ли способ прочитать этот файл csv в R, чтобы столбцы фрейма данных для авторов и ключевых слов были созданы как списки списков? И требуется ли мне форматировать файл csv определенным образом?

Чтение CSV со следующими параметрами

articles <- read.csv(file="ls.csv",head=TRUE,sep=";",stringsAsFactors=F) 

Вырабатывает Авторы Колум в виде списка, содержащего экземпляры символов. Но я пытаюсь получить список символов в каждом поле в столбце «Авторы».

ответ

1

Вы считаете, что ваш файл содержит пять переменных (идентификатор, год, название, авторы, ключевые слова), которые разделены точкой с запятой? Тогда, по определению, это не файл csv! Помните, что csv означает запятая -отделимые значения. Кто-то испортил, назвав его как таковой.

Вы можете прочитать произвольно разделителями данных с помощью read.table:

articles <- read.table("ls.csv", header=TRUE, sep=";", stringsAsFactors=FALSE) 
+3

Во многих странах запятая используется как разделитель десятичных чисел, и поэтому точка с запятой используется в файлах csv (да, они все еще называются csv-файлами) в качестве разделителя столбцов. 'read.table' работает, но для этих файлов также есть' read.csv2'. –

+0

@JanvanderLaan - «во многих странах ...» Насколько я знаю, только голландцы используют это соглашение, и это одна из причин, почему я ненавижу * использование голландской версии Excel, особенно при сотрудничестве с людьми, имеющими международный версия. +1 для упоминания 'read.csv2'! – nluigi

+1

@nluigi. Больше стран используют запятую, чем период как десятичный разделитель (возможно, не люди, такие как Китай и Индия, используют период). См. Https://en.wikipedia.org/wiki/Decimal_mark#Countries_using_Arabic_numerals_with_decimal_comma. Я не знаю, что делают электронные таблицы в этих странах. Но я согласен, что тот факт, что поведение excel зависит от локали, довольно раздражает. –

0

Как Hong Уи отметил, ваши поля, разделенные ';', а не ''. Функция read.csv имеет значение по умолчанию sep = "," while read.csv2 имеет значение по умолчанию sep = ";". Если я правильно понял, ваши поля Авторы и Ключевые слова разделены знаком «,», и вы также хотите их разделить.

Я не думаю, что вы могли бы иметь тип списка элементов в столбцах Авторы и Ключевые слова в data.frame, так как столбец data.frame не может быть списком. Если список указан в data.frame, он разбивается на его компоненты столбца. В вашем случае это не будет работать, как будет разное число авторов и/или ключевые слова:

# Works 
data.frame(a=list(first=1:3, second=letters[1:3]), b=list(first=4:6, second=LETTERS[1:3])) 
# a.first a.second b.first b.second 
#1  1  a  4  A 
#2  2  b  5  B 
#3  3  c  6  C 

# Does not work 
data.frame(a=list(first=1:3, second=letters[1:2]), b=list(first=4:6, second=LETTERS[1:6])) 
#Error in data.frame(first = 1:3, second = c("a", "b"), check.names = FALSE, : 
# arguments imply differing number of rows: 3, 2 

Но поскольку список может содержать списки, вы могли бы попытаться разбить кадр данных вплоть до таких. Содержание примера.TXT ':

ID;Year;Title;Authors;Keywords; 
1;2013;Towards Dynamic Non-obtrusive Health Monitoring Based on SOA and Cloud;Mohammed Serhani, Abdelghani Benharret, Erlabi Badidi;E-health, Diseases, Monitoring, Prevention, SOA, Cloud, Platform, m-tech; 
2;1234;Title2;Author1, Author2;Key1, Key2, Key3; 
3;5678;Title3;Author3, Author4, Author5;Key1, Key2, Key4; 

Вот пример того, как сделать это:

x <- scan("example.txt", what="", sep="\n", strip.white=TRUE) 
y <- strsplit(x, ";") 
# Leave out the header 
dat <- y[-1] 

# Apply a function to every element inside the highest level list 
dat <- lapply(dat, 
    FUN=function(x) { 
     # Splits in authors and keywords list 
     ret <- strsplit(x, ","); 
     # Remove leading and trailing whitespace 
     ret <- lapply(ret, FUN=function(z) gsub("(^ +)|(+$)", "", z)); 
     # Assign names to all the fields 
     names(ret)<-unlist(y[1]); 
     ret 
    } 
) 

Выход:

> str(dat) 
List of 3 
$ :List of 5 
    ..$ ID  : chr "1" 
    ..$ Year : chr "2013" 
    ..$ Title : chr "Towards Dynamic Non-obtrusive Health Monitoring Based on SOA and Cloud" 
    ..$ Authors : chr [1:3] "Mohammed Serhani" "Abdelghani Benharret" "Erlabi Badidi" 
    ..$ Keywords: chr [1:8] "E-health" "Diseases" "Monitoring" "Prevention" ... 
$ :List of 5 
    ..$ ID  : chr "2" 
    ..$ Year : chr "1234" 
    ..$ Title : chr "Title2" 
    ..$ Authors : chr [1:2] "Author1" "Author2" 
    ..$ Keywords: chr [1:3] "Key1" "Key2" "Key3" 
$ :List of 5 
    ..$ ID  : chr "3" 
    ..$ Year : chr "5678" 
    ..$ Title : chr "Title3" 
    ..$ Authors : chr [1:3] "Author3" "Author4" "Author5" 
    ..$ Keywords: chr [1:3] "Key1" "Key2" "Key4" 

# Keywords of first item 
> dat[[1]]$Keywords 
[1] "E-health" "Diseases" "Monitoring" "Prevention" "SOA"  
[6] "Cloud"  "Platform" "m-tech" 

# Title of second item 
> dat[[2]][[3]] 
[1] "Title2" 

# Traveling inside the list of lists, accessing the very last data element 
> lastitem <- length(dat) 
> lastfield <- length(dat[[lastitem]]) 
> lastkey <- length(dat[[lastitem]][[lastfield]]) 
> dat[[lastitem]][[lastfield]][[lastkey]] 
[1] "Key4" 

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

Смежные вопросы