R 如果子集为空,则返回NA的函数
我想要一个高效的函数或代码片段,它尝试将向量子集,如果子集中没有元素,则返回R 如果子集为空,则返回NA的函数,r,dplyr,tidyr,R,Dplyr,Tidyr,我想要一个高效的函数或代码片段,它尝试将向量子集,如果子集中没有元素,则返回NA。比如说, v1 = c(1, 1, NA) 代码unique(v1[!is.na(v1)])返回一个很好的条目,但对于 v2 = c(NA, NA, NA) 代码唯一(v2[!is.na(v2)]返回逻辑(0),当此子集操作用作包含每个摘要或摘要的dplyr链的一部分时,返回的逻辑(0)我希望第二个操作返回NA,而不是逻辑(0) 这背后的背景是,我试图使用多个spread命令来解决这个问题。上一个问题的示例数据
NA
。比如说,
v1 = c(1, 1, NA)
代码unique(v1[!is.na(v1)])
返回一个很好的条目,但对于
v2 = c(NA, NA, NA)
代码唯一(v2[!is.na(v2)]
返回逻辑(0)
,当此子集操作用作包含每个摘要或摘要的dplyr
链的一部分时,返回的逻辑(0)
我希望第二个操作返回NA
,而不是逻辑(0)
这背后的背景是,我试图使用多个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太多,问题就会出现:
# Replace last two entries in the last row with NA's
tmp_dat$Score2[6] <- NA
tmp_dat$Score3[6] <- NA
这可以通过data.table
中的dcast
轻松完成,该表可以包含多个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
,一个选项是将“Score”列收集为“long”格式,将列合并为单个列(“Time1”),然后进行排列
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
库(dplyr)
图书馆(tidyr)
聚集(tmp_数据、变量、Val、分数1:分数3)%>%
突变(TimeN='Time',Var=sub(“\\D+”,“”,Var))%>%
联合(时间1,时间n,时间,变量)%>%
排列(时间1,Val)
##A tible:3×7
#人员时间\u Post\u 1次\u Post\u 2次\u Post\u 3次\u Pre\u 1次\u Pre\u 2次\u Pre\u 3
# *
#1格雷格798084.5807884.0
#2萨利78 83.0 75 74 79.5
#3苏82 NA 81 78 84.5
谢谢@akrun。但是,如果我尝试执行其他summary
操作,可能返回空向量,summary
仍将失败。在这些情况下,我希望能够返回占位符。@Alex在dcast
中,有您使用的fun.aggregate
。@Alex我使用了dplyr解决方案进行了更新,但如果您正在寻找一些summary
解决方案,那么示例应该是不同的,第二个示例只是显示我希望这样一个函数存在的上下文。实际例子在问题的第一部分。我添加了一个粗体的问题陈述,希望更清楚。如果您知道您的行总是只返回一个值,只需在末尾添加[1]
:唯一(v2[!is.na(v2)])[1]
。否则,只需定义自己的函数:uniqueNotNAThanks。但这是否有效?我喜欢结尾的[1]
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
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