2016-10-14 7 views
7

私は日付の降順で並べられたデータフレームを持っています。dplyrを使用してNAを前または次の値とグループに置換してください

ps1 = data.frame(userID = c(21,21,21,22,22,22,23,23,23), 
      color = c(NA,'blue','red','blue',NA,NA,'red',NA,'gold'), 
      age = c('3yrs','2yrs',NA,NA,'3yrs',NA,NA,'4yrs',NA), 
      gender = c('F',NA,'M',NA,NA,'F','F',NA,'F') 
) 

私はNAは、以前の値 及びユーザIDの最初の行は、NAは、そのユーザIDグループの値の次のセットに置き換えた場合にユーザーID によってグループ化して値転嫁(交換)することを望みます。

私はこのようにdfを引き起こす必要がある私はdplyrと動物園のパッケージにこのようなものを使用しようとしています...しかし、そのは

cleanedFUG <- filteredUserGroup %>% 
group_by(UserID) %>% 
mutate(Age1 = na.locf(Age), 
    Color1 = na.locf(Color), 
    Gender1 = na.locf(Gender)) 

を働いていない:

全体に直接 zoo::na.locfを使用して
     userID color age gender 
       1  21 blue 3yrs  F 
       2  21 blue 2yrs  F 
       3  21 red 2yrs  M 
       4  22 blue 3yrs  F 
       5  22 blue 3yrs  F 
       6  22 blue 3yrs  F 
       7  23 red 4yrs  F 
       8  23 red 4yrs  F 
       9  23 gold 4yrs  F 
+0

これが役に立つかどうかを確認してください。 [NAsを最新の非NA値に置き換える](http://stackoverflow.com/questions/7735647/replacing-nas-with-latest-non-na-value)またはこれ[NA値をグループ値で置き換える](http :/stackoverflow.com/questions/23583739/replace-na-value-with-the-group-value) –

+0

@Tarakこんにちは、答えの1つがあなたの問題を解決したら、それを「受け入れ」と印を付けることを躊躇しないでください他の人もそれを見ることができます...ありがとう – agenis

答えて

17
require(tidyverse) #fill is part of tidyr 

ps1 %>% 
    group_by(userID) %>% 
    fill(color, age, gender) %>% #default direction down 
    fill(color, age, gender, .direction = "up") 

Source: local data frame [9 x 4] 
Groups: userID [3] 

    userID color age gender 
    <dbl> <fctr> <fctr> <fctr> 
1  21 blue 3yrs  F 
2  21 blue 2yrs  F 
3  21 red 2yrs  M 
4  22 blue 3yrs  F 
5  22 blue 3yrs  F 
6  22 blue 3yrs  F 
7  23 red 4yrs  F 
8  23 red 4yrs  F 
9  23 gold 4yrs  F 
1

userIDグループに関係なく、data.frameはNAを埋めます。パッケージdplyrのグループ化は、私は、スプリットと一緒に行った理由です、na.locf機能に、残念ながら効果はありません:それは何

library(dplyr); library(zoo) 
ps1 %>% split(ps1$userID) %>% 
    lapply(function(x) {na.locf(na.locf(x), fromLast=T)}) %>% 
    do.call(rbind, .) 
####  userID color age gender 
#### 21.1  21 blue 3yrs  F 
#### 21.2  21 blue 2yrs  F 
#### 21.3  21 red 2yrs  M 
#### 22.4  22 blue 3yrs  F 
#### 22.5  22 blue 3yrs  F 
#### 22.6  22 blue 3yrs  F 
#### 23.7  23 red 4yrs  F 
#### 23.8  23 red 4yrs  F 
#### 23.9  23 gold 4yrs  F 

は、それが最初に、私は転嫁の最初のパスを適用し、3 data.framesにデータを分割していることです(下向き)、次に無名関数で上向きにlapply、最後にrbindを使用してdata.framesを戻します。あなたは期待される出力を持っています。

あなたに与え
+1

あなたは 'do.call()'を 'split(。$ userID)'でより慣用的な 'bind_rows()'と 'split(ps1 $ userID)'に置き換えることができます。 –

+1

代わりに 'purrr'を使うこともできます:' library(purrr); PS1%>%slice_rows( "ユーザID")%>%by_slice(関数(X){na.locf(na.locf(X)、fromLast = T)}、.collat​​e = "行") ' –

+1

StevenBeaupréいい@!それ自身で新しい答えが必要なのです;-) – agenis

1

の方法を使用して@agenis purrrと組み合わせるna.locf()で、あなたができる:

library(purrr) 
library(zoo) 

ps1 %>% 
    slice_rows("userID") %>% 
    by_slice(function(x) { 
    na.locf(na.locf(x), fromLast=T) }, 
    .collate = "rows") 
関連する問題