Kama Jansen

Kama Jansen Student, Akademia
Medyczna w
Amsterdamie

Temat: operacje na danych z kilku plikow

Mam prosbe czy ktos moze mi pomoc napisac taka funkcje ktora liczy to samo ale dla danych z kilku plikow. Znaczy tak mam pliki ktore nazywaja sie dse....csv i w nich jest taki sam format danych, w 19 kolumnach. Aby policzyc to o co mi chodzi dla jednego pliku robie:
najpierw czytam pierwszy pliczek:
dse <- read.csv2("C:/Documents and ettings/dse02.csv", header=T)
potem obliczam o co mi chodzi:
minS1 <- tapply(dse$Sensor1,dse$measurement,min)
maxS1 <- tapply(dse$Sensor1,dse$measurement,max)
minS2 <- tapply(dse$Sensor2,dse$measurement,min)
maxS2 <- tapply(dse$Sensor2,dse$measurement,max)
minS3 <- tapply(dse$Sensor3,dse$measurement,min)
maxS3 <- tapply(dse$Sensor3,dse$measurement,max)
minS4 <- tapply(dse$Sensor4,dse$measurement,min)
maxS4 <- tapply(dse$Sensor4,dse$measurement,max)
minS5 <- tapply(dse$Sensor5,dse$measurement,min)
maxS5 <- tapply(dse$Sensor5,dse$measurement,max)
minS6 <- tapply(dse$Sensor6,dse$measurement,min)
maxS6 <- tapply(dse$Sensor6,dse$measurement,max)
minS7 <- tapply(dse$Sensor7,dse$measurement,min)
maxS7 <- tapply(dse$Sensor7,dse$measurement,max)
minS8 <- tapply(dse$Sensor8,dse$measurement,min)
maxS8 <- tapply(dse$Sensor8,dse$measurement,max)
minS13 <- tapply(dse$Sensor13,dse$measurement,min)
maxS13 <- tapply(dse$Sensor13,dse$measurement,max)
diffS1 <- maxS1 - minS1
diffS2 <- maxS2 - minS2
diffS3 <- maxS3 - minS3
diffS4 <- maxS4 - minS4
diffS5 <- maxS5 - minS5
diffS6 <- maxS6 - minS6
diffS7 <- maxS7 - minS7
diffS8 <- maxS8 - minS8
diffS13 <- maxS13 - minS13

i zapisuje do pliku wyjsciowego:
res_diff_02 <- as.data.frame(t(rbind(diffS1, diffS2, diffS3, diffS4, diffS5, diffS6, diffS7, diffS8, diffS13)))
write.csv2(res_diff_02, file="C:/Documents and Settings/res_diff_02.csv")

moj problem jest taki ze ja takich pliczkow mam dosc sporo i musialabym robic dla wszyskich recznie, ale oczywiscie lepiej zrobic w funkcji i tu jest problem...
myslalam zeby zrobic cos takiego:
setwd("C:/Documents and Settings/")

files.dse = list.files()[grep("dse", list.files())]
resultat= c()
for(i in 1:length(files.dse))

..... (tu mialyby byc obliczenia, tak jak powyzej, ale globalnie
minS1 <- tapply(dse$Sensor1,dse$measurement,min) )

write.csv2(resultat, file="C:/Documents and Settings/res_diffs[i].csv")

To oczywiscie nie dziala, bo nie wiem jak zrobic globalnie to co ma byc obliczane, a poza tym to
files.dse = list.files()[grep("dse", list.files())]
tez nie jest dobrze bo to mi daje tylko liste plikow a nie pliki.

Czy ktos wie jak to zrobic? Bede wdzieczna za pomoc.

Temat: operacje na danych z kilku plikow

Na pewno trzymasz pliki wprost w Documents and settings? W każdym razie - uzupełnij ścieżkę.

Temat referencyjny:
http://www.goldenline.pl/forum/1864156/petla-po-wszyst...

Przykładowe rozwiązanie:

katalog_plikow <- "C:/Documents and Settings/<uzupełnij ścieżkę>"

nr_pliku <- 0

rdzenNazwyPliku <- "C:/Documents and Settings/<uzupełnij sciezke>/res_diff_"

wykonaj_obliczenia <- function(plik, rdzenNazwyPliku) {

dse <- read.csv2(plik, header=T)
minS1 <- tapply(dse$Sensor1,dse$measurement,min)
maxS1 <- tapply(dse$Sensor1,dse$measurement,max)
minS2 <- tapply(dse$Sensor2,dse$measurement,min)
maxS2 <- tapply(dse$Sensor2,dse$measurement,max)
minS3 <- tapply(dse$Sensor3,dse$measurement,min)
maxS3 <- tapply(dse$Sensor3,dse$measurement,max)
minS4 <- tapply(dse$Sensor4,dse$measurement,min)
maxS4 <- tapply(dse$Sensor4,dse$measurement,max)
minS5 <- tapply(dse$Sensor5,dse$measurement,min)
maxS5 <- tapply(dse$Sensor5,dse$measurement,max)
minS6 <- tapply(dse$Sensor6,dse$measurement,min)
maxS6 <- tapply(dse$Sensor6,dse$measurement,max)
minS7 <- tapply(dse$Sensor7,dse$measurement,min)
maxS7 <- tapply(dse$Sensor7,dse$measurement,max)
minS8 <- tapply(dse$Sensor8,dse$measurement,min)
maxS8 <- tapply(dse$Sensor8,dse$measurement,max)
minS13 <- tapply(dse$Sensor13,dse$measurement,min)
maxS13 <- tapply(dse$Sensor13,dse$measurement,max)
diffS1 <- maxS1 - minS1
diffS2 <- maxS2 - minS2
diffS3 <- maxS3 - minS3
diffS4 <- maxS4 - minS4
diffS5 <- maxS5 - minS5
diffS6 <- maxS6 - minS6
diffS7 <- maxS7 - minS7
diffS8 <- maxS8 - minS8
diffS13 <- maxS13 - minS13

res_diff_02 <- as.data.frame(t(rbind(diffS1, diffS2, diffS3, diffS4, diffS5, diffS6, diffS7, diffS8, diffS13)))

write.csv2(res_diff_02, file=sprintf( "%s%i.csv", rdzenNazwyPliku, ( nr_pliku <<- nr_pliku+1) ) )

}

nazwy_plikow <- list.files(path=katalog_plikow, full.names=TRUE)

lapply(nazwy_plikow, wykonaj_obliczenia, rdzenNazwyPliku)


Wynik (uprościłem obliczenia dla celów poglądowych):

Obrazek


PS: pliki wynikowe nie muszą odpowiada numerom plików wejściowych, bo funkcja zwracająca listę plików nie sortuje ich. Jeśli będzie to konieczne, trzeba będzie napisać kod, który wytnie z oryginalnego pliku jego numer i doklei go do pliku wynikowego.

Oto kod, który pobiera numer z pliku wejściowego i wykorzystuje go do utworzenia nazwy pliku wyjściowego:
katalog_plikow <- "C:/test/"
rdzenNazwyPliku <- "c:/test/res_diff_"

wykonaj_obliczenia <- function(plik, rdzenNazwyPliku) {

dse <- read.csv2(plik, header=T, sep=",")

#..................................
minS1 <- min(dse$val1)
maxS1 <- max(dse$val1)
diffS1 <- maxS1 - minS1
#..................................

res_diff_02 <- as.data.frame(t(rbind(diffS1)))

# znajdź numer pliku z kropką (ostatni przed rozszerzeniem, o ile nie ma więcej kropek)
res <- regexpr("[0-9]+\\.{1}", plik)

# pobierz numer pliku
nr_pliku <- as.numeric(substr(plik, res, res+attr(res, "match.length")-2))

write.csv2(res_diff_02, file=sprintf( "%s%i.csv", rdzenNazwyPliku, nr_pliku ) )
}

nazwy_plikow <- list.files(path=katalog_plikow, full.names=TRUE)
lapply(nazwy_plikow, wykonaj_obliczenia, rdzenNazwyPliku)

list.files(path=katalog_plikow, full.names=TRUE)

#zawartość pliku
read.table("c:/test/res_diff_1.csv", header=TRUE,sep=",",na.strings="NA", dec=",", strip.white=TRUE)

#jako ramka
as.data.frame( read.csv2("c:/test/res_diff_1.csv", header=T) )
Adrian Olszewski edytował(a) ten post dnia 04.06.12 o godzinie 20:17
Kama Jansen

Kama Jansen Student, Akademia
Medyczna w
Amsterdamie

Temat: operacje na danych z kilku plikow

Wielkie dzieki Adrian! Dziala tak jak piszesz. Jestem wdzieczna. Moglbys mi jeszcze pomoc w ponizszym:

setwd("C:/Documents and Settings/.../controle")
files = list.files()[grep("rat02", list.files())]
resultaat.dse02 = c()
for(i in 1:length(files))
{
resultaat.dse02 = rbind(resultaat.dse02, read.csv2(files[i]))
} resultaat.dse02$Rat<-2
resultaat.dse02$Group<-"controle"
write.csv2(resultaat.dse02, file="C:/Documents and Settings/.../dse02.csv")

Ten kod dziala, ale nie do konca robi to co chce. Zanim zrobie rbind musze po pobraniu pojedynczego pliku dodawac do niego kolumne o nazwie measurement i dopisywac kolejny numer, czyli gdy pobieram plik pierwszy o nazwie zawierajacej ".....rat02" to musze do tego pliku dodac ...rat02$measurement<-1
dla drugiego pliku bedzie to ...rat02$measurement<-2
itd
problem jest taki ze nie wiem jak to dodawac do tych plikow, bo przeciez nie znam ich nazwy, znaczy znam, ale tu tych nazw nie podaje, bo sa za skomplikowane, to zlepek cyferek z "rat02", wiec dlatego tu uzywam:
files = list.files()[grep("rat02", list.files())]

Temat: operacje na danych z kilku plikow

Moment, chodzi Ci o to, skąd wziąć numerator do pliku?

Można dać zmienną "licznik" i inkrementować (1, 2, 3...), ale wtedy nie masz kontroli dla którego pliku wejściowego (list.files zwraca pliki w jakiejś tam kolejności, chyba wg daty) jest który numer pliku wyjściowego. Np. plik cośtamcośtamrat02cośtam01.csv może się przypisać do wynikowego dse32.csv.

Ale jeśli masz ten numer w nazwie pliku wejściowego, np. cośtamcośtamrat02cośtam01.csv, to można wyciąć ten numer wyrażeniem regularnym i dokleić do pliku wyjściowego czy tam do datasetu.
Kama Jansen

Kama Jansen Student, Akademia
Medyczna w
Amsterdamie

Temat: operacje na danych z kilku plikow

Nie nie, chodzi o to ze w tym moim przykladzie pobieram po kolei pliczki z:
files = list.files()[grep("rat02", list.files())]
i je rbinduje:
resultaat.dse02 = rbind(resultaat.dse02, read.csv2(files[i]))
a potem do wynikowego juz pliku dopisuje 2 kolumny Rat i Group i przypisuje im 2 i "controle"
resultaat.dse02$Rat<-2
resultaat.dse02$Group<-"controle"
i potem to zapisuje jako jeden plik dse02.csv
write.csv2(resultaat.dse02, file="C:/Documents and Settings/.../dse02.csv")

a ja bym chciala zaraz po pobraniu pliczu dodac mu kolumnie measurement w ktorej bylby numer pomiaru, czyli jak pobiore pliczek 1 to ma byc 1, dla drugiego pliczku ma byc 2 itd
bo kazdy pobierany pliczek to kolejny pomiar i to chce miec w kolumnie o nazwie measurement

recznie to bym zrobila to tak:
plik1 <- read.csv2("C:/Documents and Settings/.../043424_rat02_1.csv")
plik1$measurement<-1
plik2 <- read.csv2("C:/Documents and Settings/.../042655_rat02_2.csv")
plik2$measurement<-2
plik3 <- read.csv2("C:/Documents and Settings/.../144655_rat02_1a.csv")
plik3$measurement<-3

i potem moge te pliczki recznie zbindowac:
dse02<-rbind(plik1,plik2,plik3)
i potem tez moge dodac inne kolumny juz do tego pliczku wynikowego:
dse02$Rat<-2
dse02$Group<-"controle"
i potem moge zapisac ten pliczek jako jeden plik dse02.csv
write.csv2(dse02, file="C:/Documents and Settings/.../dse02.csv")

no ale wlasie po to chce zeby to robilo automatycznie bo ja tych pliczkow mam duuuzo, za duuuzo:)
Kama Jansen

Kama Jansen Student, Akademia
Medyczna w
Amsterdamie

Temat: operacje na danych z kilku plikow

Adrian mam jeszcze pytanie do ponizszego, bo u mnie wywala Error in split.default(X, group) : first argument must be a vector
nie wiem jak to rozwiazac, moze chodzi o to ze umnie te nazwy plikow nie nazywaja sie costamcos1, costamcos5, costamcos06 ale maja na koncu jeszcze literke przed .csv, czyli
costamcos1a, costamcos5b, costamcos06l i to chyba jest problem? ale nie jestem pewna.
Mama nadzieje ze moze uda sie w jakis prosty sposob to rozwiazac? jak nie to trudno i moze wiesz jak sie dodaje te liczby o ktorych pisalam w poprzednim poscie.
Z gory dzieki wielkie!!!

Adrian Olszewski:

# znajdź numer pliku z kropką (ostatni przed rozszerzeniem, o ile nie ma więcej kropek)
res <- regexpr("[0-9]+\\.{1}", plik)
>
# pobierz numer pliku
nr_pliku <- as.numeric(substr(plik, res, res+attr(res,
> "match.length")-2))

write.csv2(res_diff_02, file=sprintf( "%s%i.csv", rdzenNazwyPliku, nr_pliku ) )
}

nazwy_plikow <- list.files(path=katalog_plikow,
> full.names=TRUE)
lapply(nazwy_plikow, wykonaj_obliczenia, rdzenNazwyPliku)

list.files(path=katalog_plikow, full.names=TRUE)

#zawartość pliku
read.table("c:/test/res_diff_1.csv", header=TRUE,sep=",",na.strings="NA", dec=",", strip.white=TRUE)

#jako ramka
as.data.frame( read.csv2("c:/test/res_diff_1.csv", header=T) )[/code]
Kama Jansen

Kama Jansen Student, Akademia
Medyczna w
Amsterdamie

Temat: operacje na danych z kilku plikow

Hi Adrian miales racje z tym licznikiem. Zrobilam wiec tak ze najpierw dodaje kolejno numer do nowoutworzonej kolumny i potem zapisuje tak sobie te pliczki a potem dopiero je wszystkie rbinduje, moze troche naokolo, ale dziala:)

files <- "C:/Documents and Settings/kawlodzimirow/.../controle"
file.nr <- 0
file_name <- "C:/Documents and Settings/.../dseratc02_"

fun.change <- function(file, file_name) {
dserat <- read.csv2(file, header=T)
for(i in 1:length(files))
{
dserat$measurement<-file.nr+i
}
dserat$Rat<-2
dserat$Group<-"controle"

write.csv2(dserat, file=sprintf( "%s%i.csv", file_name, (file.nr <<- file.nr+1) ) )
}
files.names <- list.files(path=files, full.names=TRUE)
lapply(files.names, fun.change, file_name)

> Adrian Olszewski:
Moment, chodzi Ci o to, skąd wziąć numerator do pliku?

Można dać zmienną "licznik" i inkrementować (1, 2, 3...)

Temat: operacje na danych z kilku plikow

No i fajnie. Na potrzeby Twoich zagadnień nie trzeba robić tu jakichś szczególnych optymalizacji, więc najważniejsze, że działa - to raz, a dwa, że sama do tego doszłaś :) Nie ma lepszej nauki jak samodzielna próba rozwiązania problemu i kopanie po książkach/sieci.

Następna dyskusja:

Wczytywanie danych z pliku ...




Wyślij zaproszenie do