2016-11-04 4 views
2

벡터를 부분 집합하려고하는 효율적인 함수 또는 코드 조각을 원하고 하위 집합에 요소가없는 경우 NA을 반환합니다. 예를 들어,부분 집합이 비어있는 경우 NA를 반환하는 함수

v1 = c(1, 1, NA) 

코드 unique(v1[!is.na(v1)]) 반환 한 대단한 항목 만

v2 = c(NA, NA, NA) 

코드에 대한 unique(v2[!is.na(v2)]) 반환이 부분 집합 조작이의 일부로서 사용된다 크지 않다 logical(0), dplyr 체인은 summarise_each 또는 summarise을 함유한다. logical(0) 대신 NA을 반환하는 두 번째 작업을 원합니다.

이 배경의 배경은 복수 spread 명령을 사용하여 this question을 해결하려고하는 것입니다. 우리는 (다른 열 이름 불구) 원하는 출력 달성 할 수있는 다수의 확산을 이용하여, 이제

set.seed(10) 
tmp_dat <- data_frame(
    Person = rep(c("greg", "sally", "sue"), each=2), 
    Time = rep(c("Pre", "Post"), 3), 
    Score1 = round(rnorm(6, mean = 80, sd=4), 0), 
    Score2 = round(jitter(Score1, 15), 0), 
    Score3 = 5 + (Score1 + Score2)/2 
) 

> tmp_dat 
Source: local data frame [6 x 5] 

    Person Time Score1 Score2 Score3 
    <chr> <chr> <dbl> <dbl> <dbl> 
1 greg Pre  80  78 84.0 
2 greg Post  79  80 84.5 
3 sally Pre  75  74 79.5 
4 sally Post  78  78 83.0 
5 sue Pre  81  78 84.5 
6 sue Post  82  81 86.5 

: 예 데이터 이전 질문에서 촬영도있을 경우 지금

tmp_dat %>% 
    mutate(Time_2 = Time, 
      Time_3 = Time) %>% 
    spread(Time, Score1, sep = '.') %>% 
    spread(Time_2, Score2, sep = '.') %>% 
    spread(Time_3, Score3, sep = '.') %>% 
    group_by(Person) %>% 
    summarise_each(funs(((function(x)x[!is.na(x)])(.)))) 

를 문제가 생긴다 많은 NA의는 :

: 이제 summarise_each로 코드를 실행

# Replace last two entries in the last row with NA's 
tmp_dat$Score2[6] <- NA 
tmp_dat$Score3[6] <- NA 

오류를 발생 우리는 dplyr/tidyr을 사용해야하는 경우

Error in eval(substitute(expr), envir, enclos) : expecting a single value 
이 쉽게 걸릴 수있는 data.table에서 dcast 수행 할 수 있습니다
+1

라인이 항상 하나의 값을 반환한다는 것을 안다면, 끝에 '[1]'을 추가하면됩니다 : unique (v2 [! is.na (v2)]) [1]'. 그렇지 않으면 자신 만의 함수를 정의하면된다.'uniqueNotNA <-function (x) {ind <-! is.na (x); if (sum (ind) == 0) NA else unique (x [ind])}'. – nicola

+0

감사합니다. 이것은 효율적이긴하지만? 나는 끝에 [1]을 좋아한다 – Alex

답변

1

여러 value.var

library(data.table) 
dcast(setDT(tmp_dat), Person ~paste0("Time.", Time), 
       value.var = c("Score1", "Score2", "Score3")) 
#  Person Score1_Time.Post Score1_Time.Pre Score2_Time.Post Score2_Time.Pre Score3_Time.Post Score3_Time.Pre 
#1: greg    79    80    80    78    84.5   84.0 
#2: sally    78    75    78    74    83.0   79.5 
#3: sue    82    81    NA    78    NA   84.5 

이 옵션은 'gather에'점수 '컬럼 것 긴 형식으로 unite 열을 단일 열 ('Time1')에 입력 한 다음 수행하십시오. spread

library(dplyr) 
library(tidyr) 
gather(tmp_dat, Var, Val, Score1:Score3) %>% 
      mutate(TimeN = 'Time', Var = sub("\\D+", "", Var)) %>% 
      unite(Time1, TimeN, Time, Var) %>% 
      spread(Time1, Val) 
# # A tibble: 3 × 7 
# Person Time_Post_1 Time_Post_2 Time_Post_3 Time_Pre_1 Time_Pre_2 Time_Pre_3 
# * <chr>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl> 
#1 greg   79   80  84.5   80   78  84.0 
#2 sally   78   78  83.0   75   74  79.5 
#3 sue   82   NA   NA   81   78  84.5 
+0

고마워요 @akrun. 그러나 다른'summarize' 연산을 시도하면 빈 벡터를 리턴 할 수 있습니다.'summarise'는 여전히 실패합니다. 이러한 상황에서 자리 표시자를 반환 할 수 있기를 바랍니다. – Alex

+0

@Alex'dcast'에는 여러분이 사용하는'fun.aggregate'가 있습니다. – akrun

+0

@Alex dplyr 솔루션으로 업데이트했지만, 몇 가지 요약 솔루션을 찾고 있다면 예제는 달라야합니다. – akrun