質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.51%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

4回答

3331閲覧

csvへの出力

hkhk0

総合スコア14

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2016/05/20 11:46

###実現したいこと
下記のような内容のcsvファイルを出力させたいと思っています。

"name","score1","socore2","average" "A","40","69","54.5" "B","19","18","18.5" "C","20","12","16" "D","70","41","55.5" "E","77","78","77.5"

###試したこと
sample.csv

"name","score01","score02" "A","40","69" "B","19","18" "C","20","12" "D","70","41" "E","77","78"

lang

1require "csv" 2infile = "sample.csv" 3outfile = "sample_r.csv" 4 5csv = CSV.read(infile) 6header = csv.first, "average" 7i = 0 8CSV.open(outfile, "w", :headers => header, :write_headers => true) do |f| 9 CSV.foreach(infile, headers: true) do |row| 10 csvtable = CSV.table(infile) 11 ave = (row[1].to_f + row[2].to_f) / 2 12 f << [csvtable[i], ave] 13 i = i + 1 14 end 15end 16

実行結果
sample_r.csv

"[""name"", ""score01"", ""score02""]",average "A,40,69 ",54.5 "B,19,18 ",18.5 "C,20,12 ",16.0 "D,70,41 ",55.5 "E,77,78 ",77.5

不自然なコードかもしれませんが、この様な書き方で出力させるにはどのように修正すればよろしいでしょうか?
また、中途半端に改行されたり[]や”が入ってしまうのはなぜでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

CSV:Table を使って書いてみました。

ruby

1require 'csv' 2infile = 'sample.csv' 3outfile = 'sample_r.csv' 4 5table = CSV.table(infile) 6table.map { |row| row[:average] = (row[:score01] + row[:score02]) / 2.0 } 7File.write(outfile, table)

実行結果:
sample_r.csv

name,score01,score02,average A,40,69,54.5 B,19,18,18.5 C,20,12,16.0 D,70,41,55.5 E,77,78,77.5

参考情報:

投稿2016/05/22 00:21

katoy

総合スコア22322

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

意図しない形式になるのは、まずヘッダについては、csv.first, "average"がおかしいです。
値としては[["name", "score01", "score02"], "average"]になって、二重の配列なのでcsvに書き出すと結果のようになってしまいます。

データ行は、f << [csvtable[i], ave]の部分が、f << [csvtable[i], ave].to_sつまりf << csvtable[i].to_s + ave.to_sと同様になるためです。csvtable[i].to_sで、改行が付くようです。

また、infileのループの中で、csvtable = CSV.table(infile)と毎回infileをファイル全部読み出すのはおかしいです。そもそも不要だし、読むにしてもループの外で。

ヘッダの処理を今ひとつマスターできてませんが、とりえあえずこんな感じで。

Ruby

1CSV.open(infile) do |csv| 2 hdr = csv.gets 3 hdr << "average" 4 CSV.open(outfile, "w", force_quotes: true, write_headers: true, headers: hdr) do |f| 5 csv.each do |row| 6 ave = (row[1].to_f + row[2].to_f) / 2 7 row << ave 8 f << row 9 end 10 end 11end

投稿2016/05/20 16:05

otn

総合スコア84380

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hkhk0

2016/05/21 07:45

ご回答有り難うございます。詳しい解説を有り難うございます。とても参考になりました。
guest

0

ベストアンサー

こうすればいいかと

ruby

1require "csv" 2infile = "sample.csv" 3outfile = "sample_r.csv" 4 5csv = CSV.read(infile) 6header = csv.first << "average" 7i = 0 8CSV.open(outfile, "w", :headers => header, :write_headers => true, :force_quotes => true) do |f| 9 CSV.foreach(infile, headers: true) do |row| 10 csvtable = CSV.table(infile) 11 ave = (row[1].to_f + row[2].to_f) / 2 12 f << (csvtable[i] << ave) 13 i = i + 1 14 end 15end

型の違いが今回のバグの原因みたいです。
csv.firstは["name","score01","score02"]という配列で"avarage"は文字列ですね。
CSV gemは配列を改行のキーとしている節があるので、ヘッダーの謎の改行と[]は配列の中に配列が入っちゃったからでしょう。
また、レコードの謎の改行は[CSVオブジェクト,文字列]の配列が原因でしょう。

投稿2016/05/20 14:06

編集2016/05/20 14:15
oskbt

総合スコア1895

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hkhk0

2016/05/21 07:43

ご回答有り難うございます。お陰様で解決することができました。なるほど、[CSVオブジェクト,文字列]ってなってしまってたのですね。
guest

0

header = csv.first, "average" で、CSVの1行目と、文字を書き込んでます。""average""としても、カギカッコが残ります。文字変数に csv.first & "average"みたいな1行とするでしょうか、私なら。
それと、2回書き込んでます。これも、一つにして1回書き込むと良いかも。

投稿2016/05/20 12:37

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hkhk0

2016/05/21 05:54

ご回答有り難うございます。改めて検討させていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.51%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問