2016-10-14 3 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의 그룹에 대한 값의 다음 세트로 교체 될 경우 아이디 그룹화하여 값 전가 (교체)하기 바란다.

이 같은 dplyr 및 동물원 패키지 뭔가를 사용하려고 ...하지만 내가 될 필요

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

작동하지 DF 같은 :

     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 안녕하세요, 답변 중 하나가 문제를 해결하는 경우 주저하지 말고 '수락 함'으로 표시하세요. 다른 사람들도 그것을 볼 수 있습니다 ... 감사합니다 – 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

전체에 직접 zoo::na.locf 사용 data.frame은 userID 그룹과 관계없이 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 (. $ userID)' –

+1

다른 idiomatic'bind_rows()'와'split (ps1 $ userID)'로'do.call() 'purrr'을 사용하는 또 다른 방법은 :'library (purrr); ps300 % @ slice_rows ("userID") %> % by_slice (함수 (x) {na.locf (na.locf (x), fromLast = T)}, .collate = "행")' –

+1

@ StevenBeaupré nice! 그 자체로 새로운 대답을 할 자격이 있습니다 ;-) – agenis

1

purrr과 함께 na.locf()와 방법을 @agenis 사용하여, 당신은 할 수 :이 도움이 경우

library(purrr) 
library(zoo) 

ps1 %>% 
    slice_rows("userID") %>% 
    by_slice(function(x) { 
    na.locf(na.locf(x), fromLast=T) }, 
    .collate = "rows") 
관련 문제