2017-05-05 108 views
1

我有一個包含60個檔案與.circles擴展名的文件夾中。全部都是文本文件。數據和CSV粘貼中的R

文件名:239.circles

內容:

circle17: 306 281 
circle16: 335 253 

我想將它轉換成一個CSV名爲train.csv

有兩列:用戶名和預測

在用戶ID的行,我應該得到的文件名如: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,其中i應該得到239(因爲我讀文件239.circles),並在第2列我應該得到:306 281; :335 253(沒有額外的:後)

+0

而是寫作for循環爲什麼不使用map或lapply?請參閱https://rud.is/b/2016/07/26/use-quick-formula-functions-in-purrrmap-base-vs-tidtyverse-idiom-comparisonsexamples/ – biomiha

+1

我認爲您的程序存在一個問題(忽略'for'循環):你寫的每一次'trains.csv'文件'i'在循環等覆蓋舊的 –

+0

請刪除我以前的解決方案,並與您的早期循環取代。我認爲你的行爲較早前的工作,但我沒有檢查,看看你沒推斷'UserID'在循環,如用正確@wolf_wue指出。我在下面添加了一個解決方案,它應該可以工作。 –

回答

0

下面是與dplyr包的溶液:

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") 

編輯:

由於有可變長度,以每一行,這將是有意義的構建data.frame,每行中id = circleX和val =連續值。

這裏是一個簡短的功能,可以這樣做:

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 

接下來,讓我們定義可以在用戶標識的線增加一個功能。 Userid基於「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 

其餘的很簡單 - readLines列出所有文件;定義在每個文件名的用戶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,函數(x)的讀取。表格(text = x)[2:3]) 掃描錯誤(file = file,what = what,sep = sep,quote = quote,dec = dec,: 第1行沒有188個元素 –

+0

示例圓圈文件可以在這個鏈接上看到,有一個可以下載的Training.zip文件https://www.kaggle.com/c/learning-social-circles/data。 –

+0

啊。每行可變長度。將會有所不同,請稍後再回復 –