R语言 通过选择非NA值总结变量的覆盖率

7bsow1i6  于 2023-06-27  发布在  其他
关注(0)|答案(5)|浏览(143)

假设我有一个如下所示的 Dataframe

ID Year Var1 Var2 Var3 Var4
1  2001  1    1     3    NA
2  2001  2    3     8     7
3  2002  NA   4     2     1
4  2003  2    8     NA    8
5  2006  NA   NA    NA    NA
6  2007  2    NA    8     8
7  2007  6    7     7     3

我需要确定每个变量的覆盖范围。只要变量有一个非NA观测值,它就被覆盖(例如,Var4在2001年被覆盖,因为即使它有一个NA,它也有一个实际值)
我想总结所有变量的覆盖率,将pivot year作为列名,将变量作为行,每个覆盖变量year的单元格都有一个1。所需的输出如下:

Var 2001 2002 2003 2006 2007
Var1 1    0    1    0    1
Var2 1    1    1    0    1
Var3 1    1    0    0    1
Var4 1    1    1    0    1

我相信这应该是可能的dplyr,但我还没有找到正确的组合pivot_widersummarise执行这种重新格式化。

pprl5pva

pprl5pva1#

+(xtabs(values~.,cbind(stack(df, -(1:2)), Year = factor(df[,'Year'])))>0)
      Year
ind    2001 2002 2003 2006 2007
  Var1    1    0    1    0    1
  Var2    1    1    1    0    1
  Var3    1    1    0    0    1
  Var4    1    1    1    0    1
df %>%
  pivot_longer(starts_with('Var'))%>%
  pivot_wider(names_from = Year, id_cols = name, values_fn = ~+any(!is.na(.)))

      name   `2001` `2002` `2003` `2006` `2007`
     <chr>   <int>  <int>  <int>  <int>  <int>
    1 Var1       1      0      1      0      1
    2 Var2       1      1      1      0      1
    3 Var3       1      1      0      0      1
    4 Var4       1      1      1      0      1
df %>%
  pivot_longer(starts_with('Var'))%>%
  summarise(value = +any(!is.na(value)), .by = c(Year, name))%>%
  pivot_wider(names_from = Year, id_cols = name)

 name  `2001` `2002` `2003` `2006` `2007`
  <chr>  <int>  <int>  <int>  <int>  <int>
1 Var1       1      0      1      0      1
2 Var2       1      1      1      0      1
3 Var3       1      1      0      0      1
4 Var4       1      1      1      0      1
w9apscun

w9apscun2#

您可以使用aggregate尝试以下基本R选项

d <- aggregate(
    . ~ Year, df[-1],
    Negate(anyNA),
    na.action = na.pass
)
setNames(data.frame(names(d)[-1], +t(d[-1])), c("Var", d$Year))

它给出了

Var 2001 2002 2003 2006 2007
Var1 Var1    1    0    1    0    1
Var2 Var2    1    1    1    0    0
Var3 Var3    1    1    0    0    1
Var4 Var4    0    1    1    0    1
68bkxrlz

68bkxrlz3#

一句话,基地R。

cbind(Var=names(df[3:6]), +rbind.data.frame(by(df[3:6], df$Year, \(x) !sapply(x, anyNA))))
#    Var X2001 X2002 X2003 X2006 X2007
# 1 Var1     1     0     1     0     1
# 2 Var2     1     1     1     0     0
# 3 Var3     1     1     0     0     1
# 4 Var4     0     1     1     0     1
tf7tbtn2

tf7tbtn24#

您可以首先总结任何未丢失的位置,然后转置data.frame。

library(tidyverse)
   df <- tribble(~ID, ~Year, ~Var1, ~Var2, ~Var3, ~Var4,
                  1,  2001  ,1    ,1     ,3    ,NA,
                  2 , 2001  ,2    ,3     ,8     ,7,
                  3  ,2002  ,NA   ,4     ,2     ,1,
                  4  ,2003  ,2    ,8     ,NA    ,8,
                  5  ,2006  ,NA   ,NA    ,NA    ,NA,
                  6  ,2007  ,2    ,NA    ,8     ,8,
                  7  ,2007  ,6    ,7     ,7     ,3) 

df2 <- df %>% 
    group_by(Year) %>% 
    summarise(across(starts_with("Var"),function(x){any(!is.na(x))})) 

df_t = data.frame(t(df2[, -1]))
colnames(df_t) = df2[, 1, drop = TRUE]
8nuwlpux

8nuwlpux5#

以下是我的Tidyverse解决方案:

df |>
  group_by(Year) |>
  summarise(across(Var1:Var4, \(x) +any(!is.na(x)))) |>
  pivot_longer(Var1:Var4, names_to="Var", values_to = "Coverage") |>
  pivot_wider(names_from = Year, values_from = "Coverage")

相关问题