Kamil Bęczyński

Kamil Bęczyński R, SAS, analizy

Temat: W jaki sposób zapisać i wczytać listę ?

W jaki sposób zapisać do pliku i wczytać listę, a konkretnie, przy pomocy sink() zapisano listę do pliku, wygląda ona tak :

[[1]]
[1] 1 2
[[2]]
[1] 1 2 3

zawiera same liczby, w jaki sposób wczytać coś takiego ?
planuję spróbować wczytać to jako character.Kamil Bęczyński edytował(a) ten post dnia 25.04.12 o godzinie 01:44
Michał Bojanowski

Michał Bojanowski socjolog, analityk

Temat: W jaki sposób zapisać i wczytać listę ?

jak rozumiem chodzi o to, zeby zapisac i wczytac do/z pliku tekstowego. zapisac/wczytac do/z pliku binarnego mozna save i load.

do pliku tekstowego mozna zapisac na przykład funkcją 'dput' a potem wczytac 'dget'. na pewno nie bawil bym sie w pisanie parsera do eRowego outputu.....

jezeli komponentami listy sa tylko wektory liczb to mozna tez zapisac kazdy komponent jako wiersz cyfr oddzielonych spacjami (nawet 'cat' do tego wystarczy), a potem wczytac 'readLines' i pociąć wartości 'strsplit'.

Temat: W jaki sposób zapisać i wczytać listę ?

Jeśli to koniecznie musi być plik zapisany sinkiem, to jest trochę roboty z tym...

Przygotowania
 > sink("c:\\plik")
> lista <- list(c(1:2), c(1:3))
> lista
> sink(NULL)
> plik <- scan("c:\\plik", what=character(0))
Read 9 items
> plik
[1] "[[1]]" "[1]" "1" "2" "[[2]]" "[1]" "1" "2" "3"


Wyszukujemy pozycje kolejnych wektorów szukając "otwierających je" podwójnych nawiasów:
 > pozycjeLewychNawiasow <- which(substr(plik, 1, 2) == "[[")
> pozycjeLewychNawiasow
[1] 1 5


Teraz wyliczamy ile jest wartości między 1szym elementem a drugim, drugim a i-tym, i-tym a ostatnim:
 > diff(c(pozycjeLewychNawiasow, length(plik) + 1))
[1] 4 5


Mamy łącznie 1:length(pozycjeLewychNawiasow) wektorów. Dla każdego wektora utworzymy sekwencję indeksów, wg których potem podzielimy zmienną z zawartością pliku ("plik")

rep(1:length(pozycjeLewychNawiasow), diff(c(pozycjeLewychNawiasow, length(plik) + 1 )))
[1] 1 1 1 1 2 2 2 2 2


A teraz dzielimy plik wg sekwencji indeksów.
 > (wektory <- split(plik, rep(1:length(pozycjeLewychNawiasow), diff(c(pozycjeLewychNawiasow, length(plik) + 1 )))))
$`1`
[1] "[[1]]" "[1]" "1" "2"

$`2`
[1] "[[2]]" "[1]" "1" "2" "3"


Almost there! Z każdego wektora trzeba wywalić indeksy w nawiasach, zarówno pojedynczych jak i podwójnych. Znajdźmy ich indeksy:
 > substr(plik, 1, 1)
[1] "[" "[" "1" "2" "[" "[" "1" "2" "3"

> which(substr(plik, 1, 1)=="[")
[1] 1 2 5 6


... i wywalmy nawiasy
 > plik[-which(substr(plik, 1, 1)=="[")]
[1] "1" "2" "1" "2" "3"


Zastosujmy tę metodę do każdego elementu listy wektorów ("wektory")
 > (czysteListy <- lapply(wektory, function(x) x[-which(substr(x, 1, 1)=="[")]))
$`1`
[1] "1" "2"

$`2`
[1] "1" "2" "3"


I na koniec zamieńmy na liczby:
 > (numListy <- lapply(czysteListy, as.numeric))
$`1`
[1] 1 2

$`2`
[1] 1 2 3


Na koniec można wyczyścić nazwy elementów listy:
 > names(numListy) <- NULL
> numListy
[[1]]
[1] 1 2

[[2]]
[1] 1 2 3


Ufffff :D

W skrócie:
 > pozycjeLewychNawiasow <- which(substr(plik, 1, 2) == "[[")
> wektory <- split(plik, rep(1:length(pozycjeLewychNawiasow), diff(c(pozycjeLewychNawiasow, length(plik) + 1 ))))
> czysteListy <- lapply(wektory, function(x) x[-which(substr(x, 1, 1)=="[")])
> numListy <- lapply(czysteListy, as.numeric)
> names(numListy) <- NULL
> numListy
[[1]]
[1] 1 2

[[2]]
[1] 1 2 3


Shit, Michał miał rację ;)

----------------------

Działa także dla danych tekstowych:
 > sink("c:\\plik")
> ( lista <- list(c("Ala", "ma", "kota"), c("Zosia", "ma", "psa")))
> sink(NULL)
> (plik <- scan("c:\\plik", what=character(0)))
Read 10 items
[1] "[[1]]" "[1]" "Ala" "ma" "kota" "[[2]]" "[1]" "Zosia" "ma" "psa"

> (pozycjeLewychNawiasow <- which(substr(plik, 1, 2) == "[["))
[1] 1 6

> (wektory <- split(plik, rep(1:length(pozycjeLewychNawiasow), diff(c(pozycjeLewychNawiasow, length(plik) + 1 )))))
$`1`
[1] "[[1]]" "[1]" "Ala" "ma" "kota"

$`2`
[1] "[[2]]" "[1]" "Zosia" "ma" "psa"

> (czysteListy <- lapply(wektory, function(x) x[-which(substr(x, 1, 1)=="[")]))
$`1`
[1] "Ala" "ma" "kota"

$`2`
[1] "Zosia" "ma" "psa"

> names(czysteListy) <- NULL
> czysteListy
[[1]]
[1] "Ala" "ma" "kota"

[[2]]
[1] "Zosia" "ma" "psa"
Adrian Olszewski edytował(a) ten post dnia 25.04.12 o godzinie 14:14
Michał Bojanowski

Michał Bojanowski socjolog, analityk

Temat: W jaki sposób zapisać i wczytać listę ?

zmudna i brudna robota, no własnie w to nie chcialem sie bawic. :) a co jezeli komponenty listy mają nazwy? poza tym, sink lamie wiersze uzywając getOptions("width") wiec jezeli komponenty listy są na tyle długie, ze wektory sa drukowane w wiecej niz jednym wierszu, to tez trzeba to uwzglednic....

Adrianie, Kamilu, nie podążajcie tą drogą ;)

Temat: W jaki sposób zapisać i wczytać listę ?

Ależ broń Boże, dla mnie tylko XMLe, CSV albo binarki :) Po prostu padło hasło "sink", no to jedziemy z sinkiem w najprostszej postaci ;) Ot taka łamigłówka...
Wojciech Sobala

Wojciech Sobala Redaktor
statystyczny,
biostatystyk,
Instytut Medycyny
Pr...

Temat: W jaki sposób zapisać i wczytać listę ?

Ja bym to zrobił tak:


lista <- readLines("nazwa_pliku")
lista <- lista[grepl("^[1]", lista)
lista <- sub("^[1] ","", lista)
lista_num <- lapply(strsplit(lista,split=" ", fixed=TRUE), as.numeric)

Temat: W jaki sposób zapisać i wczytać listę ?

Wojtku, od Ciebie można się tylko uczyć (m.in. zwięzłego zapisu R) :)

Następna dyskusja:

W jaki sposób dodać...




Wyślij zaproszenie do