2017-11-28 12 views
4

分散ファイルシステムの多くの.csvファイルに1億の行が格納されています。私は問題なくデータを読み込むためにspark_read_csv()を使用しています。私の列の多くは、文字論理値として格納されます:"true""false""<na>"。私はこれを支配していない。sparklyrで文字列をRの論理に変換する

論理値に変換しようとすると、"<na>"の値はの値を持つFALSEに変換されます。どのようにこれを克服するための任意の考え?

test_lgl <- 
    tibble(a = c(TRUE, TRUE, NA, NA, FALSE, FALSE), 
     b = c("true", "true", "na", "<na>", "false", "f")) 

test_lgl %>% mutate_if(is.character, as.logical) 

# this works 
    a  b 
    <lgl> <lgl> 
1 TRUE TRUE 
2 TRUE TRUE 
3 NA NA 
4 NA NA 
5 FALSE FALSE 
6 FALSE NA 

sc <- spark_connect(master = "local") 
spark_lgl <- copy_to(sc, test_lgl) 

spark_lgl %>% mutate_if(is.character, as.logical) 

# this does not 
     a  b 
    <lgl> <lgl> 
1 TRUE TRUE 
2 TRUE TRUE 
3 FALSE FALSE 
4 FALSE FALSE 
5 FALSE FALSE 
6 FALSE FALSE 
+1

直接関連していません... https://github.com/rstudio/sparklyr/issues/127 – Masoud

答えて

4

私は論理的に値を変換しようとすると、"<na>"値がFALSE

驚くべきことがないに変換されます。あなたは、さらにその結果を検査した場合:

spark_lgl_boolean <- spark_lgl %>% mutate_if(is.character, as.logical) 
spark_lgl_boolean %>% mutate_all(is.na) 

Applying predicate on the first 100 rows 
# Source: lazy query [?? x 2] 
# Database: spark_connection 
     a  b 
    <lgl> <lgl> 
1 FALSE FALSE 
2 FALSE FALSE 
3 TRUE TRUE 
4 TRUE TRUE 
5 FALSE FALSE 
6 FALSE FALSE 

これはNA countと一致している:

spark_lgl_boolean %>% 
    mutate_all(is.na) %>% 
    mutate_all(as.numeric) %>% 
    summarize_all(sum) 
# Source: lazy query [?? x 2] 
# Database: spark_connection 
     a  b 
    <dbl> <dbl> 
1  2  2 

スパークexecution plan

spark_lgl %>% mutate_if(is.character, as.logical) %>% optimizedPlan 
Applying predicate on the first 100 rows 
<jobj[1074]> 
    org.apache.spark.sql.catalyst.plans.logical.Project 
    Project [a#10, cast(b#11 as boolean) AS b#2037] 
+- InMemoryRelation [a#10, b#11], true, 10000, StorageLevel(disk, memory, deserialized, 1 replicas), `test_lgl` 
     +- *FileScan csv [a#10,b#11] Batched: false, Format: CSV, Location: InMemoryFileIndex[file:/tmp/..., PartitionFilters: [], PushedFilters: [], ReadSchema: struct<a:boolean,b:string> 

とするためのロジックをキャストスパーク- >BooleanTypeここ

  • ストリングTRUE/T(大文字と小文字を区別しない)と1がリテラルtrueに変換されます。
  • 文字列FALSE/F(大文字と小文字は区別されません)と0は、リテラルのfalseに変換されます。
  • 上記と一致しない文字列はNULL(〜NA)に変換されます。
scala> Seq("tRUE", "FALSE", "f", "<na>", "NA", "1", "0").toDF("x").select($"x".cast("boolean")).show 
+-----+ 
| x| 
+-----+ 
| true| 
|false| 
|false| 
| null| 
| null| 
| true| 
|false| 
+-----+ 

問題は、具体的sparklyr変換によって導入されているように見えます。 GitHubのImprove Serializationを参照してください(これについては、kevinykuoへのクレジット)。

しかし、Sparkベースのロジックに固執すると、データをRにフェッチせずに、データをファイルに書き込むなど、うまく動作します。

私はあなたがnullValueを見て、CSV readernanValueoptionsかもしれないその場合には、データ

をロードするためにspark_read_csv()を使用しています。たとえば:

spark_read_csv(..., options=list(nullValue="<na>")) 

または

spark_read_csv(..., options=list(nanValue="<na>")) 

が、心に留めておいてください、NULL/NaNのスパークセマンティクスはR NA/NaNと同じではありません。

関連する問題