2014-02-15 5 views
0

Я пишу функцию, которая открывает все файлы в директории(), делает некоторые вычисления и перегруппировку, а затем снова пишет (write.table) каждый файл в директории()Запись файлов с в виде серий цикла

dir() 
[1] "v2p1" "v2p10" "v2p11" "v2p12" "v2p2" "v2p3" "v2p4" "v2p5" "v2p6" "v2p7" 
[11] "v2p8" "v2p9" "v2r1" "v2r10" "v2r11" "v2r12" "v2r2" "v2r3" "v2r4" "v2r5" 
[21] "v2r6" "v2r7" "v2r8" "v2r9" "v2s1" "v2s10" "v2s11" "v2s12" "v2s2" "v2s3" 
[31] "v2s4" "v2s5" "v2s6" "v2s7" "v2s8" "v2s9" 

Код выглядит так, и он делает все отлично, за исключением того, что цикл не работает.

mysub <- function(x) {sub(",",".",x)} 
abrir<-function(etapa){ 
### volnum c(1:10) indica en qué vol quiero, 
### etapa c("p","r","s") indica en qué etapa es del experimento 

i<-1 
for (i in dir()){ 

##### ABRIR ARCHIVOS DESDE DIR() ###### 
Archivo<-paste(getwd(),"/",i,sep="") 
r1<-read.table(Archivo,fill=T,sep=",") 

##### CALCULAR LA VELOCIDAD DE CADA CORRIDA ###### 
r11 <- (apply(r1, 2, mysub)) 
r1<- data.frame(apply(r11, 2, as.numeric)) ## ojo que pueden aparecer NA 
R1<-r1[1:3136,]  ### OJO, DEPENDE LA CORRIDA, SACA LOS VALORES DEL FINAL QUE NO SIRVEN 
V<-data.frame(rbind(c(0,0,0,0),(abs(diff(as.matrix(R1[,2:5])))))) 
Tiempo<-R1[,1] 
Velocidad<-data.frame(Tiempo,V) 

##### GUARDAR LAS VELOCIDADES QUE CORRESPONDEN ###### 

if (grep("p",i)==TRUE){ 
salida<-paste("VEL",i,".txt",sep="") 
write.table(Velocidad,salida,sep="\t",row.names=FALSE) 
} else if (grep("r",i)==TRUE){ 
salida<-paste("VEL",i,".txt",sep="") 
write.table(Velocidad,salida,sep="\t",row.names=FALSE) 
}else if(grep("s",i)==TRUE){ 
salida<-paste("VEL",i,".txt",sep="") 
write.table(Velocidad,salida,sep="\t",row.names=FALSE) 
}else stop("etapa inválida") 
i<-i+1 
} 
} 

abrir() спасает меня правильный «VELv2p1.txt» и возвращает эту ошибку Ошибка в I + 1: нечисловой аргумент для бинарного оператора

Я не знаю, как объяснить R продолжить со вторым элементом, как только это будет сделано i = 1 Я думаю, что я не знаю, как это сделать. Буду признателен за вашу помощь.

ответ

1

Сообщение об ошибке связано с тем, что в вашей петле i есть объект character, а не numeric. Синтаксис for(i in dir()) дает фактические файлы в i, а не в индексе. При использовании for, нет необходимости устанавливать i в следующий пункт, цикл for займет это. Поэтому просто удаление i <- i + 1 решит вашу проблему.

Некоторые замечания по поводу вашего кода:

  • отступов улучшит читаемость кода. Как и добавление пробелов.
  • Вы можете поместить вызов write.table в конце функции, сохранив три идентичные строки кода. На самом деле, набор из if заявлений, похоже, выполняет тот же код.
  • for Петли, как правило, не самые лучшие варианты в R. Векторизованные или apply основанные на решении решения дают более короткий, а иногда и более быстрый код.

Я бы грубо принять следующий подход:

list_of_files = list.files('.') 
do_some_calculations = function(file, output_name) { 
    output_name = sprintf('VEL%d.txt', list_of_files) 
    Archivo<-paste(getwd(), "/", i, sep = "") 
    r1<-read.table(Archivo,fill = T, sep = ",") 
    r11 <- (apply(r1, 2, mysub)) 
    r1<- data.frame(apply(r11, 2, as.numeric)) ## ojo que pueden aparecer NA 
    R1<-r1[1:3136,]  ### OJO, DEPENDE LA CORRIDA, SACA LOS VALORES DEL FINAL QUE NO SIRVEN 
    V <- data.frame(rbind(c(0,0,0,0), (abs(diff(as.matrix(R1[,2:5])))))) 
    Tiempo <- R1[,1] 
    Velocidad <- data.frame(Tiempo, V) 
    write.table(Velocidad, output_name,s ep="\t", row.names=FALSE) 
} 
+0

Спасибо. Я понял, что вы думаете. Мне не нравится цикл for, но я думал, что это единственный способ. Теперь цикл проходит через весь v2pi и перестает возвращать эту ошибку. Ошибка в if (grep ("p", i) == TRUE) {: аргумент имеет длину 0. Я использовал grep, потому что его матчи trhough такие персонажи, как my i –

+0

Забудьте об этом, я исчерпал инструкции if и отлично работал, спасибо! –

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