2017-05-05 12 views
1

拡張子が.circlesの60個のファイルを含むフォルダがあります。すべてがテキストファイルです。ファイルからデータを読み込み、csvで貼り付けてください。

ファイル名:私は2つのカラムを持つ単一のCSVという名前train.csv

に変換したい

circle17: 306 281 
circle16: 335 253 

内容239.circlesユーザーIDおよび予測を

UserIdの行では、ファイル名を取得する必要があります。例:239と予測の行には、円で区切られた値を取得する必要があります。例:306 281; 335 253

これを@Adamのおかげで今私が取得しています、私がこれまでに行ったこと

setwd("D:/r/social/Expt/Training") 
files <- list.files(pattern = "*.circles") 


readFn <- function(i) { 
    f <- readLines(i,n=-1,con) 
    f <-sub("^[^:]*","",f) 
    f <- paste(f, collapse=';') 
    return(f) 
} 

all.files <- lapply(files, readFn) 
output <- do.call(rbind, all.files) 

write.csv(output,"train.csv") 

出力は

1です:306 281; :335 253

私はそれを239 306 281; 335 253としたいと思います。ここで、カラム1の下には239(私はファイル239.circlesを読んでいるので)を取得し、カラム2の下に私は得るべきです:306 281; :335 253:;それぞれの行に変数の長さがあるので、それを構築するために理にかなって

all_files <- lapply(files, readLines) 
all_dat <- lapply(all_files, function(x)read.table(text=x)[2:3]) 

userid <- gsub(".circles", "", files) #this step extract the UserID based the "X.circle" file names 
all_dat <- lapply(1:length(all_dat), function(x) all_dat[[x]] %>% mutate(UserId = userid[x])) 

output <- do.call(rbind, all_dat) 
write.csv(output,"trains.csv") 

編集(追加なし後)

+0

代わりの書き込みforループなぜマップやlapplyを使用しないのですか? https://rud.is/b/2016/07/26/use-quick-formula-functions-in-purrrmap-base-vs-tidtyverse-idiom-comparisonsexamples/ – biomiha

+1

あなたの手順には1つの問題があると思います。 'for'ループ):あなたのループに' i'が入るたびに 'trains.csv'ファイルを書いて、古いものを上書きします –

+0

私の以前の解決策を削除し、以前のループに置き換えてください。私はあなたの行動が早い段階で動いていると思ったが、@wolf_wueが正しく指摘したように、あなたのループ内の 'UserID'を推測していないことを確認しなかった。私は以下の解決策を追加しました。これはうまくいくはずです。 –

答えて

0

はここdplyrパッケージとソリューションですid = circleX、val =各行の連続する値を持つ各行のdata.frame。ここで

がそうする短い機能です:

perCircle <- function(x){ 
    tmp <- read.table(text=x) 
    id <- unlist(tmp[1]) 
    id <- gsub("circle","", gsub(":", "", id)) 
    out <- data.frame(id, t(tmp)[-1]) 
    names(out) <- c("id","val") 
    return(out) 
} 

## example for how perCircle works: 

x <- "circle830: 10788 10439 10690 10642 10551" 
perCircle(x) 

    id val 
1 830 10788 
2 830 10439 
3 830 10690 
4 830 10642 
5 830 10551 

次は、ラインにユーザーIDに追加することができる機能を定義してみましょう。ユーザーIDは "X.circle"ファイル名に基づいています。

addUser <- function(x, id){ 
    out <- perCircle(x) 
    data.frame(Userid=id, out) 
    } 

# example: the defined x above is taken from "10395.circles" line 7 
addUser(x, "10395") 

    Userid id val 
1 10395 830 10788 
2 10395 830 10439 
3 10395 830 10690 
4 10395 830 10642 
5 10395 830 10551 

残りの部分は非常に簡単です。すべてのファイルをリストとして表示します。それぞれのファイル名にユーザーIDベースの定義:

files <- list.files("./Training", pattern=".circle", full=T) 
all_files <- lapply(files, readLines) 

userid <- gsub(".circles", "", list.files("./Training", pattern=".circle")) 

output <- ldply(1:length(all_files), function(x) 
       ldply(all_files[[x]], addUser, id=userid[x])) 
write.csv(output,"trains.csv") 



output[c(100,500,1000, 1500), ] # example of 4 lines within the long data.frame 

    Userid id val 
100 10395 377 10424 
500 10929 839 10984 
1000 11186 989 15007 
1500 12800 62 13256 

あなたは出力がで区切られた値を持つベクトルとしてのvalを持つようにしたい場合は、「;」、とperCircle機能を変更します。

perCircle <- function(x){ 
    tmp <- read.table(text=x) 
    id <- unlist(tmp[1]) 
    id <- gsub("circle","", gsub(":", "", id)) 
    tmp <- paste(unlist(tmp[-1]), collapse=";") 
    out <- data.frame(id, tmp) 
    names(out) <- c("id","val") 
    return(out) 
} 

## example: 
perCircle(x) 

    id       val 
1 830 10788;10439;10690;10642;10551 
+0

all_dat < - lapply(all_files、function(x)read)。 スキャンでエラーが発生しました(ファイル=ファイル、what = what、sep = sep、quote = quote、dec = dec、: 行1には188個の要素がありません –

+0

サンプルサークルファイルはこのリンクで見ることができます。ダウンロードできるTraining.zipファイルがあります。https://www.kaggle.com/c/learning-social-circles/data –

+0

ah。各行の可変長です。 –

関連する問題