2017-08-08 15 views
2

スパークデータフレーム内でNA/NULLを最も近い隣に割り当てる必要があります。私はRの背景から来たので、私はsparklyrを使用しますが、それを行う方法を理解することはできません。ここスパークデータフレーム内のNA/NULLの埋め込み

は、例えば、コードされ:

set.seed(1)  
example <- data.frame (ID = 1:10, Cat = letters[1:5], 
         Numb = sample(c(NA, NA, NA, NA, 1:10), 10)) 
    ID Cat Numb 
    1 1 a NA 
    2 2 b 1 
    3 3 c 3 
    4 4 d 6 
    5 5 e NA 
    6 6 a 5 
    7 7 b 4 
    8 8 c 9 
    9 9 d 10 
    10 10 e NA 

だからID2ナム1、番号4および6(6または5)のいずれかにID 5、およびIDにNumbの列、ID 1 NAを充填したいです10〜9の値(10)。 Rで簡単に実行できます。 Sparklyrを通じてSparkでそれを行うには、とにかくありますか?私は連続した行で複数のNA値を持っている場合はもちろん

example$Numb1 <- example$Numb[c(1,1:(nrow(example)-1))] 
example$Numb2 <- example$Numb[c(2:(nrow(example)), nrow(example))] 
example$Merge <- ifelse(is.na(example$Numb), ifelse(is.na(example$Numb1), 
example$Numb2, example$Numb1), example$Numb) 

    ID Cat Numb Numb1 Numb2 Merge 
1 1 a NA NA  1  1 
2 2 b 1 NA  3  1 
3 3 c 3  1  6  3 
4 4 d 6  3 NA  6 
5 5 e NA  6  5  6 
6 6 a 5 NA  4  5 
7 7 b 4  5  9  4 
8 8 c 9  4 10  9 
9 9 d 10  9 NA 10 
10 10 e NA 10 NA 10 

は、物事をより複雑に得ることができます。

は、ここに私のR・ソリューションです。たぶん別の提案をすることもできます。

しかし、スパークリエの場合、私は何ができるのかという手がかりはありません。

答えて

1

ここには、dplyrパッケージのSQLクエリとmutateの機能を持つ部分的に機能するソリューションがあります。それはあなたのベースRソリューションの翻訳であるため、連続した行の複数のNA値の状況には対処しませんが、他の(より完全な)アプローチには役立つかもしれません。

私はHiveQLのLag and Lead関数を使用して、列の "シフト"を実行しました。これには、「Numb1」と「Numb2」の列を保持する新しい補助Sparkテーブル(example2)の作成が含まれます。補助テーブルが作成された後に続いて、あなたはサイドノートとしてmutate

library(DBI) 
library(sparklyr) 
library(dplyr) 

set.seed(1)  
exampleDF <- data.frame (ID = 1:10, Cat = letters[1:5], 
         Numb = sample(c(NA, NA, NA, NA, 1:10), 10)) 

# Connection to Spark and creation of the table to test. 
sc <- spark_connect("local") 
example <- copy_to(sc, exampleDF) 

# Create a Spark table with columns Numb1 and Numb2 
DBI::dbSendQuery(sc, "CREATE TABLE example2 AS (SELECT ID, Cat, Numb, LAG(Numb, 1) over (PARTITION BY 1 ORDER BY ID) AS Numb1, 
      LEAD(Numb, 1) over (PARTITION BY 1 ORDER BY ID) AS Numb2 FROM exampledf)") 

# Load the auxiliary table as a Spark DataFrame 
ex2 <- tbl(sc, "example2") 

# Mutate in order to create the Merged column 
res <- ex2 %>% 
    mutate(Merged = ifelse(is.na(Numb), ifelse(is.na(Numb1), Numb2, Numb1), Numb)) 

res 

# Source: lazy query [?? x 6] 
# Database: spark_connection 
     id cat numb numb1 numb2 Merged 
    <int> <chr> <int> <int> <int> <int> 
1  1  a NA NA  1  1 
2  2  b  1 NA  3  1 
3  3  c  3  1  6  3 
4  4  d  6  3 NA  6 
5  5  e NA  6  5  6 
6  6  a  5 NA  4  5 
7  7  b  4  5  9  4 
8  8  c  9  4 10  9 
9  9  d 10  9 NA  10 
10 10  e NA 10 NA  10 

で「合併」の列を作成することができます、またmutate機能(およびすべてのifelse S)の使用を避けることができることにより、機能はCOALESCEです。私はこれがはるかに効率的だと思います。

DBI::dbGetQuery(sc, "SELECT ID, Cat, Numb, COALESCE(Numb, Numb1, Numb2) AS Merged FROM example2") 
    ID Cat Numb Merged 
1 1 a NA  1 
2 2 b 1  1 
3 3 c 3  3 
4 4 d 6  6 
5 5 e NA  6 
6 6 a 5  5 
7 7 b 4  4 
8 8 c 9  9 
9 9 d 10  10 
10 10 e NA  10 

これが役立ちます。あなたがすべてでSQLを使用しないようにしたい場合は、あなたがdplyr関数でもそれを行うことができます

編集

example %>% arrange(ID) %>% 
    mutate(Numb1 = lag(Numb, 1)) %>% 
    mutate(Numb2 = lead(Numb, 1L)) %>% 
    mutate(Merged = ifelse(is.na(Numb), ifelse(is.na(Numb1), Numb2, Numb1), Numb)) 
# Source:  lazy query [?? x 6] 
# Database: spark_connection 
# Ordered by: ID 
     ID Cat Numb Numb1 Numb2 Merged 
    <int> <chr> <int> <int> <int> <int> 
1  1  a NA NA  1  1 
2  2  b  1 NA  3  1 
3  3  c  3  1  6  3 
4  4  d  6  3 NA  6 
5  5  e NA  6  5  6 
6  6  a  5 NA  4  5 
7  7  b  4  5  9  4 
8  8  c  9  4 10  9 
9  9  d 10  9 NA  10 
10 10  e NA 10 NA  10 
# ... with more rows 

私はいくつかのトラブル二つの連続mutate符号化機能を持っていた(私が使用理由です最初は混合SQL-dplyrアプローチ)。私はsparklyrにissueを開いてしまった。

+0

私は遅延と鉛が最も有用なものだと思います!ありがとうJaime! –

+0

@KevinZhengよろしくお願いします。:-) –