在R中将多个列与NA值组合,但如果没有列具有数据,则仅使用NA

时间:2017-05-11 19:25:41

标签: r dplyr tidyr

如果有关如何改进我的代码的建议,我将不胜感激。第二次尝试工作并提供所需的输出,但我认为这非常繁琐。也许有一个更简单的解决方案。

原始数据集包含8列,其中包含有关屏幕分辨率的信息。每列代表一组不同的问题,参与者被随机分配,这意味着如果在该特定集合中没有询问解决问题,则插入NA,尽管参与者可能已在不同的集合中回答了问题。

我有匿名和简化数据,只包括我提到的原始八列中的三个:

05-12 03:14:41.983  5014  5014 D hole    : single clicked0
05-12 03:14:43.066  5014  5014 D hole    : single clicked1
05-12 03:14:43.615  5014  5014 D hole    : positive clicked:-1

我的目标是将所有集合组合成一个名为Resolutions的列;但是,只有当一个特定行包含所有集合/列中的NA值时,才将其标记为NA,如果一个集合包含分辨率,则只应将分辨率值写入该列。

我尝试以下依赖dplyr和tidyr包,这是我的两次尝试。

第一次尝试使用mutate和paste0:

    ID  ResSet1 ResSet2 ResSet3
1   NA  NA  NA
2   NA  NA  NA
3   NA  NA  NA
4   NA  NA  NA
5   NA  1280x800    NA
6   NA  NA  NA
7   NA  NA  NA
8   NA  NA  NA
9   NA  1440x900    NA
10  NA  NA  1366x768
11  NA  NA  NA
12  NA  NA  NA
13  NA  NA  NA
14  NA  1366x768    NA
15  NA  NA  NA
16  NA  NA  1920x1080
17  NA  NA  NA
18  1600x1200   NA  NA
19  NA  NA  NA
20  NA  NA  1366x768
21  NA  NA  1440x900
22  NA  1680x1050   NA
23  1600x900    NA  NA
24  NA  NA  NA
25  NA  NA  1920x1080
26  NA  NA  NA
27  NA  1440x900    NA
28  NA  NA  NA
29  NA  NA  1600x900
30  1280x800    NA  NA

这导致如下所示:(从原始数据集输出)

x = test %>% mutate(Resolution = paste0(ResSet1, ResSet2, ResSet3))

我在使用paste0时没有弄清楚如何做rm.na函数,所以在我第二次尝试使用unite时;我已用“”替换NA字符串,然后用适当的NA替换空单元格。

    x$Resolution

1] "NANANANANANANA1366x768"  "NANA1440x900NANANANANA"  "NANANANANANA1344x840NA"  "NANANANA1366x768NANANA" 
      [5] "NA1280x800NANANANANANA"  "NANANANANANANA1366x768"  "NANANANA1366x768NANANA"  "NANANANANANA1536x864NA" 
      [9] "NA1440x900NANANANANANA"  "NANANA1366x768NANANANA"  "NANANANANANANA1280x800"  "NANANANANA1366x768NANA" 
     [13] "NANA1408x792NANANANANA"  "NA1366x768NANANANANANA"  "NANANANANA1920x1080NANA" "NANANA1920x1080NANANANA"

结果如下所示:(原始数据集输出)

x2 = test %>% unite(Resolution, ResSet1, ResSet2, ResSet3, 
                     remove = TRUE, sep = "") %>% 
  mutate(Resolution = str_replace_all(Resolution, "NA", "")) %>%
  mutate(Resolution = ifelse(Resolution == "", NA, Resolution))

这实际上是我需要实现的目标;但是,这个解决方案对我来说似乎并不优雅,也许对此有一个更简单的方法。

感谢您的建议。

2 个答案:

答案 0 :(得分:2)

coalesce可用于选择几个向量的相应值的第一个非NA值:

library(dplyr)

df <- df %>% 
    mutate_at(vars(contains('ResSet')), as.character) %>%    # ensure all are character, not factor
    mutate(Resolutions = coalesce(ResSet1, ResSet2, ResSet3))    # coalesce

tail(df)
#>    ID  ResSet1  ResSet2   ResSet3 Resolutions
#> 25 25     <NA>     <NA> 1920x1080   1920x1080
#> 26 26     <NA>     <NA>      <NA>        <NA>
#> 27 27     <NA> 1440x900      <NA>    1440x900
#> 28 28     <NA>     <NA>      <NA>        <NA>
#> 29 29     <NA>     <NA>  1600x900    1600x900
#> 30 30 1280x800     <NA>      <NA>    1280x800

答案 1 :(得分:1)

您可以在基础R中轻松完成此操作 - 我假设第一列是ID而其他所有列都是分辨率列:

df$res <- df[cbind(seq_len(nrow(df)), max.col(!is.na(df[-1]))+1)]