计算 grouped_df dplyr 中非 NA 列的数量
count number of non-NA columns in a grouped_df dplyr
我正在尝试在我的 .df
中创建一个列,它给出了(非 NA)列数的值。这在数据未分组的情况下很简单,因为我可以使用 ncol()
或 dim(df)[2]
。我的问题是尝试在 df 中的组上使用这些函数中的任何一个,特别是当我对数据进行分组时,一些列变为空(然后我将其删除,因此列大小在不同分组之间发生变化)。
示例:
data(iris)
iris$fake.dat1 <- rnorm(1:50)
iris$fake.dat2 <- rnorm(1:50)
iris$fake.dat3 <- rnorm(1:50)
# make some groups be all NA for some columns
iris$fake.dat1[iris$Species == 'setosa'] <- NA
iris$fake.dat2[iris$Species == 'setosa' | iris$Species == 'virginica'] <- NA
我想在我的数据框中添加一列,用于计算每个物种的非 NA 列的数量。我使用了 janitor 包中的函数 remove_empty_cols
。
到目前为止,我已经尝试过:
iris %>%
group_by(Species) %>%
remove_empty_cols(.) %>%
mutate(num.col = ncol(.))
这给出了一个全八的列。如果我将数据过滤到每个组,那么上面的内容似乎有效:
iris %>%
filter(Species == 'setosa') %>%
remove_empty_cols(.) %>%
mutate(num.col = ncol(.))
如有任何建议,我们将不胜感激!
这取决于变量是否可能具有 NA
对于组中的某些(但不是全部)值,以及您希望如何计算这些行或组。
如果您只想要每行的非NA
值的数量,解决方案非常简单:
library(tidyverse)
# add partial NA column
iris <- iris %>% mutate(fake.dat3 = ifelse(fake.dat3 < 0, NA, fake.dat3))
iris1 <- iris %>% mutate(num.col = rowSums(!is.na(.)))
table(iris1$num.col)
#>
#> 5 6 7 8
#> 21 50 50 29
如果您想要计算每个组中具有一些非 NA
值的列的数量,则稍微复杂一些:
iris2 <- iris %>%
nest(-Species) %>%
mutate(num.col = map_int(data, ~sum(map_lgl(.x, ~!all(is.na(.x)))))) %>%
unnest()
table(iris2$num.col)
#>
#> 5 6 7
#> 50 50 50
如果您想要计算没有 any NA
的每个组的列数,请将 all
更改为 any
:
iris3 <- iris %>%
nest(-Species) %>%
mutate(num.col = map_int(data, ~sum(map_lgl(.x, ~!any(is.na(.x)))))) %>%
unnest()
table(iris3$num.col)
#>
#> 4 5 6
#> 50 50 50
对于原始数据,所有方法都会 return 相同的结果,但如您所见,在真实数据上可能不会。
我正在尝试在我的 .df
中创建一个列,它给出了(非 NA)列数的值。这在数据未分组的情况下很简单,因为我可以使用 ncol()
或 dim(df)[2]
。我的问题是尝试在 df 中的组上使用这些函数中的任何一个,特别是当我对数据进行分组时,一些列变为空(然后我将其删除,因此列大小在不同分组之间发生变化)。
示例:
data(iris)
iris$fake.dat1 <- rnorm(1:50)
iris$fake.dat2 <- rnorm(1:50)
iris$fake.dat3 <- rnorm(1:50)
# make some groups be all NA for some columns
iris$fake.dat1[iris$Species == 'setosa'] <- NA
iris$fake.dat2[iris$Species == 'setosa' | iris$Species == 'virginica'] <- NA
我想在我的数据框中添加一列,用于计算每个物种的非 NA 列的数量。我使用了 janitor 包中的函数 remove_empty_cols
。
到目前为止,我已经尝试过:
iris %>%
group_by(Species) %>%
remove_empty_cols(.) %>%
mutate(num.col = ncol(.))
这给出了一个全八的列。如果我将数据过滤到每个组,那么上面的内容似乎有效:
iris %>%
filter(Species == 'setosa') %>%
remove_empty_cols(.) %>%
mutate(num.col = ncol(.))
如有任何建议,我们将不胜感激!
这取决于变量是否可能具有 NA
对于组中的某些(但不是全部)值,以及您希望如何计算这些行或组。
如果您只想要每行的非NA
值的数量,解决方案非常简单:
library(tidyverse)
# add partial NA column
iris <- iris %>% mutate(fake.dat3 = ifelse(fake.dat3 < 0, NA, fake.dat3))
iris1 <- iris %>% mutate(num.col = rowSums(!is.na(.)))
table(iris1$num.col)
#>
#> 5 6 7 8
#> 21 50 50 29
如果您想要计算每个组中具有一些非 NA
值的列的数量,则稍微复杂一些:
iris2 <- iris %>%
nest(-Species) %>%
mutate(num.col = map_int(data, ~sum(map_lgl(.x, ~!all(is.na(.x)))))) %>%
unnest()
table(iris2$num.col)
#>
#> 5 6 7
#> 50 50 50
如果您想要计算没有 any NA
的每个组的列数,请将 all
更改为 any
:
iris3 <- iris %>%
nest(-Species) %>%
mutate(num.col = map_int(data, ~sum(map_lgl(.x, ~!any(is.na(.x)))))) %>%
unnest()
table(iris3$num.col)
#>
#> 4 5 6
#> 50 50 50
对于原始数据,所有方法都会 return 相同的结果,但如您所见,在真实数据上可能不会。