27545


データ前処理を関数化しようと試みておりますが、3つほど気になるところがありエラーが出てしまうので質問させていただきます。よろしくお願い致します。

1, 関数の中に関数を入れても問題がないのでしょうか。  
以下の関数で`num`がきちんと働いてくれるか気になります。

[code]

    syori <- function(variables,num){  
    setwd("C:\\Users\\hoge\\Desktop")
    names <- list.dirs("csv", full.names = F, recursive = FALSE)
    files <- list.files("csv", full.names = F, pattern="csv",recursive = FALSE)
    reading <- function(x){
    library(dplyr)
    setwd("C:\\Users\\hoge\\Desktop")
    kaerichi<- fread(x) %>% select_(variables)%>% 
    filter(Q1 == num) %>% 
    mutate(cnum=num)
    return(kaerichi)
    }
     for (i in names) {
    setwd("C:\\Users\\hoge\\Desktop\\csv")
    mypath <- file.path(getwd(), paste0(i,".csv"))
      assign(i, reading(mypath))
     }
    }
      all <- rbind(paste(names,collapse=",")) %>% as.data.frame()
      return(all)
    }
    
[/code]

2,また、上記の関数の中の`fread`に対して以下のエラーが出てしまいます。  
どのように対処すべきでしょうか？  
`file.names`でとった`"hoge.csv"`の形と  
`file.path(getwd(), file.names)`から`.csv`を落としたもの)でとった  
`"C:\\Users\\hoge\\Desktop"`の形の両方共試しています。

[code]

    Error in fread(x) : 
    'input' must be a single character string containing a file name,
    a command, full path to a file,
    a URL starting 'http[s]://', 'ftp[s]://' or 'file://', or the input data itself
    
[/code]

3, `file.names`で取得したファイル名を`assign`でデータフレーム名にし、`rbind`で一気にタテに結合したいのですが  
`rbind(file.names(hogehoge))`でいけるものでしょうか？  
`file.names`だと`chr`の型になっているのでカンマ区切りにする必要があるでしょうか？

<http://qiita.com/uri/items/e162302ce8a38b009660> を参照しました。

**3の解答**  
3が自己解決？したので追記しておきます。  
`paste0(file.names,collapse=",")`で全部つながりました。

**追記**

[code]

    child2 <- syori(quote(c(ID,hensuu,...,Q122)),2)
    
[/code]

を実行すると、`quote`の中身が返ってきて困っています。  
本来ならディレクトリの中のcsvをうまく処理したものが帰ってくるはずなのですが。

**追記2**

[code]

    all <- rbind(paste(names,collapse=","))
    
[/code]

が原因のようです。rbindの中を手書きにするとうまくいくのですが。  
paste0にしても変わらないです。型はcharacterです。

→crayfish44さんの投稿を参考に

[code]

    rbind(eval(parse(text=paste0(names,collapse=","))))
    
[/code]

と書き換えましたが

[code]

    Error in parse(text = paste0(names, collapse = ",")) : 
    <text>:1:4: unexpected ','
    
[/code]

というエラーが出ます。


CC BY-SA 3.0
2016-07-11T06:20:16.367
27524
2017-06-20T16:08:29.553
2017-06-20T16:08:29.553
12457
12457
question
r csv dplyr
データ前処理の関数化について


回答として適切かわかりませんが単に連番からなるファイルを読み込むには、  
foreachパッケージを使うと楽だったりします。foreach()関数の引数に.combineというものがあり、  
これにrbind（行方向での結合）を指定し、対象のファイル名の番号の部分をiterationとして与えると勝手に結合してくれます。

パイプ演算子を使って読み込み後の処理を加えることも可能です。

[code]

    library(foreach)
    # 対象のファイル名がfile1, file2, ... file9という場合
    syori <- function(hoge, files, ...) {
      foreach(i = 1:files, .combine = rbind) %do% {
        data.table::fread(
          paste0(hoge, i, ".csv")
        ) 
      }
    }
    
    syori(hoge = "file", files = 2)
    
[/code]


CC BY-SA 3.0
2016-07-11T10:45:42.817
27532
2016-07-11T10:45:42.817
6020
27524
answer


`assign()`したデータフレーム名 (`names`ではなく`files`の方を用いています) を`eval(parse(text =
~))`で処理する方法でやってみました。`eval(parse(text =
files)`では`files`の最後の要素のみしか読んでくれないため、`lapply()`でリストに出力し`bind_rows()`で全リスト要素を結合させ、最後に`tbl`を`data.frame`化しています
(もう少しスマートにやれると思います)。`setwd("C:\\ ~ \\csv")` に iris1.csv、同2、同3
を置いた環境で動作確認をしています
(csvの中身は全てirisで、`Q1`の代わりに`Sepal.Length`を使用)。また、私の環境では`select_`周りのコードが通らなかったため、若干変更しております。

[code]

    ### テスト用環境作成
    setwd("C:\\Users\\hoge\\Desktop\\csv")
    write.csv(iris, "iris1.csv", quote=FALSE, row.names=FALSE)
    write.csv(iris, "iris2.csv", quote=FALSE, row.names=FALSE)
    write.csv(iris, "iris3.csv", quote=FALSE, row.names=FALSE)
    
    ### メイン
    syori <- function(variables, num){  
      setwd("C:\\Users\\hoge\\Desktop\\csv")
      files <- list.files(full.names = F, pattern="csv", recursive = FALSE)
      reading <- function(x){
        library(dplyr)
        library(data.table)
        kaerichi<- fread(x) %>% select(one_of(variables)) %>% 
          filter(Sepal.Length == num) %>% 
          mutate(cnum = num)
        return(kaerichi)
      }
      for (i in files) {
        mypath <- file.path(getwd(), i)
        assign(i, reading(mypath))
      }
      all <- lapply(files, function(x) eval(parse(text = x))) %>% 
               bind_rows() %>% as.data.frame()
      return(all)
    }
    
    ### テスト
    syori(c("Sepal.Length", "Petal.Length", "Species"), 6.8)
    
    #   Sepal.Length Petal.Length    Species cnum
    # 1          6.8          4.8 versicolor  6.8
    # 2          6.8          5.5  virginica  6.8
    # 3          6.8          5.9  virginica  6.8
    # 4          6.8          4.8 versicolor  6.8
    # 5          6.8          5.5  virginica  6.8
    # 6          6.8          5.9  virginica  6.8
    # 7          6.8          4.8 versicolor  6.8
    # 8          6.8          5.5  virginica  6.8
    # 9          6.8          5.9  virginica  6.8
    
[/code]


CC BY-SA 3.0
2016-07-11T16:20:43.747
27545
2016-07-11T16:48:40.867
2016-07-11T16:48:40.867
15653
15653
27524
answer