如果子集为空则返回NA的函数

时间:2016-11-04 05:01:23

标签: r dplyr tidyr

我想要一个有效的函数或代码片段来尝试对向量进行子集化,如果子集中没有元素,则返回NA。例如,对于

v1 = c(1, 1, NA)

代码unique(v1[!is.na(v1)])返回一个很棒的条目,但对于

v2 = c(NA, NA, NA)

当此子集化操作用作包含unique(v2[!is.na(v2)])logical(0)的{​​{1}}链的一部分时,代码dplyr会返回summarise_each,这不是很好。 我希望第二个操作返回summarise而不是NA

这背后的背景是我尝试使用多个logical(0)命令来解决this question。从上一个问题中获取的示例数据:

spread

现在,使用多个点差我们可以获得所需的输出(尽管列名不同):

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

现在,如果NA太多了,就会出现问题:

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)])(.))))

现在运行带有# Replace last two entries in the last row with NA's tmp_dat$Score2[6] <- NA tmp_dat$Score3[6] <- NA 的代码段会产生错误:

summarise_each

1 个答案:

答案 0 :(得分:1)

使用来自dcast的{​​{1}}可以轻松完成此操作,这可能需要多个data.table

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 ,则可以选择将dplyr/tidyr'得分'列设置为'长'格式,将gather列添加到单个列('Time1')然后执行unite

spread