web-dev-qa-db-ja.com

as.numericとコンマの小数点区切り文字

次の形式の文字列の大きなベクトルがあります。

_Input = c("1,223", "12,232", "23,0")
_

など。つまり、ピリオドではなく、コンマで区切られた小数。このベクトルを数値ベクトルに変換したい。残念ながら、as.numeric(Input)NAを出力するだけです。

私の最初の本能はstrsplitに行くことですが、これはおそらく非常に遅いと思われます。誰もがより速いオプションのアイデアを持っていますか?

_read.csv2_を示唆する既存の質問がありますが、問題の文字列はそのように直接読み取られません。

35
Fhnuzoag
as.numeric(sub(",", ".", Input, fixed = TRUE))

動作するはずです。

50
adibender
_scan(text=Input, dec=",")
## [1]  1.223 12.232 23.000
_

ただし、ベクターの長さに依存します。 rep(Input, 1e6)を使用して長いベクトルを作成すると、マシンがハングします。ただし、_1e4_は問題ありません。 @adibenderのソリューションははるかに高速です。 1e4で実行すると、lotが速くなります。

_Unit: milliseconds
         expr        min         lq     median         uq        max neval
  adibender()   6.777888   6.998243   7.119136   7.198374   8.149826   100
 sebastianc() 504.987879 507.464611 508.757161 510.732661 517.422254   100
_
12
sebastian-c

また、生データを読み込む場合は、read.tableおよび関連するすべての関数には、dec引数があります。例えば:

read.table("file.txt", dec=",")

他のすべてが失敗した場合、gsubsubは友達です。

6
Ricardo Saporta

@adibenderソリューションの構築:

input = '23,67'
as.numeric(gsub(
                # ONLY for strings containing numerics, comma, numerics
                "^([0-9]+),([0-9]+)$", 
                # Substitute by the first part, dot, second part
                "\\1.\\2", 
                input
                ))

私はそれがより安全な試合だと思う...

4
Deena

で述べたように、ファイルのインポート中にこれを行う方が簡単です。最近リリースされた reads パッケージには、非常に便利な機能localeがあり、よく説明されている here を使用すると、locale = locale(decimal_mark = ",")を引数として。

2
Emiliano

複数のコンマがある場合、adibenderによる答えは機能しません。

その場合、use554546からの提案とDeenaからの回答を使用できます。

Input = c("1,223,765", "122,325,000", "23,054")
as.numeric(gsub("," ,"", Input))

出力:

[1] 1223765 122325000 23054

関数gsubは、すべての出現を置き換えます。関数subは最初のもののみを置き換えます。

1

readrパッケージには、文字列から数値を解析する機能があります。 locale引数を使用して多くのオプションを設定できます。

小数点としてカンマの場合、次のように記述できます。

readr::parse_number(Input, locale = readr::locale(decimal_mark = ","))
1
tspano