4

のような範囲であるいくつかのフィールドを持つ .tsv ファイルがあります1 - 4。これらのフィールドはテキストで書かれているので読みたいです。ただし、ファイルを開くと、Excel は自動的にこれらの範囲フィールドを日付に変換します。たとえば、1 - 4に変換され4-Janます。セルを別の型にフォーマットし直そうとすると、値は既に変更されており、役に立たない数値 (39816) しか取得できません。範囲フィールドが二重引用符で囲まれている場合でも、日付への間違った変換が引き続き行われます。この動作を回避するにはどうすればよいですか?

4

5 に答える 5

0

私の質問は、実際には少なくとも次の複製です。

1) Excel が特定のテキスト値を日付に自動的に変換しないようにする

2) Excel: .csv ファイルを開くときに、GENERAL ではなく TEXT をデフォルトに設定する

Excel で考えられる解決策は、1) as のような特別な二重引用符でフィールドを書き込むか、"May 16, 2011"2 "=""May 16, 2011""") 外部データ ウィザードを使用して csv/tsv ファイルをインポートし、GENERAL ではなく TEXT として読み取る列を手動で選択することです (フィールドを日付に変換できます)

私の使用例に関しては、Excel のみを使用していくつかの列を削除していました。特別な引用符で tsv ファイルを書き直したくないし、何百もの列があり、それぞれを手動で選択して TEXT として読み取りたくなかったため、どのソリューションも魅力的ではありませんでした。

したがって、列名で tsv ファイルをフィルター処理するための scala スクリプトを作成しました。

package com.jmcejuela.ml

import java.io.InputStream
import java.io.Writer

import scala.io.Codec
import scala.io.Source

import Table._

/**
 * Class to represent tables with a fixed size of columns. All rows have the same columns.
 */
class Table(val rows: Seq[Row]) {
  lazy val numDiffColumns = rows.foldLeft(Set[Int]())((set, row) => set + row.size)

  def toTSV(out: Writer) {
    if (rows.isEmpty) out.write(TableEmpty.toString)
    else {
      out.write(writeLineTSV(rows.head.map(_.name))) //header
      rows.foreach(r => out.write(writeLineTSV(r.map(_.value))))
      out.close
    }
  }

  /**
   * Get a Table with only the given columns.
   */
  def filterColumnsByName(columnNames: Set[String]): Table = {
    val existingNames = rows.head.map(_.name).toSet
    assert(columnNames.forall(n => existingNames.contains(n)), "You want to include column names that do not exist")
    new Table(rows.map { row => row.filter(col => columnNames.contains(col.name)) })
  }

}

object TableEmpty extends Table(Seq.empty) {
  override def toString = "Table(Empty)"
}

object Table {
  def apply(rows: Row*) = new Table(rows)

  type Row = Array[Column]

  /**
   * Column representation. Note that each column has a name and a value. Since the class Table
   * is a sequence of rows which are a size-fixed array of columns, the name field is redundant
   * for Table. However, this column representation could be used in the future to support
   * schemata-less tables.
   */
  case class Column(name: String, value: String)

  private def parseLineTSV(line: String) = line.split("\t")
  private def writeLineTSV(line: Seq[String]) = line.mkString("", "\t", "\n")

  /**
   * It is assumed that the first row gives the names to the columns
   */
  def fromTSV(in: InputStream)(implicit encoding: Codec = Codec.UTF8): Table = {
    val linesIt = Source.fromInputStream(in).getLines
    if (linesIt.isEmpty) TableEmpty
    else {
      val columnNames = parseLineTSV(linesIt.next)
      val padding = {
        //add padding of empty columns-fields to lines that do not include last fields because they are empty
        def infinite[A](x: A): Stream[A] = x #:: infinite(x)
        infinite("")
      }
      val rows = linesIt.map { line =>
        ((0 until columnNames.size).zip(parseLineTSV(line) ++: padding).map { case (index, field) => Column(columnNames(index), field) }).toArray
      }.toStream
      new Table(rows)
    }
  }
}
于 2013-04-10T13:09:13.197 に答える
0

日付形式に再フォーマットされていた値「8013-07-8」の化学キャスンが入力されているExcelの「テキスト」形式のセルがありました。この問題を解決するために、値の先頭に一重引用符を連結すると、結果を表示したときに正しくレンダリングされました。セルをクリックすると、接頭辞付きの一重引用符が表示されますが、少なくとも日付として表示されなくなりました。

于 2018-03-27T14:41:24.373 に答える