如何使用 dplyr::c_across() 对不同类型的变量进行汇总
How to summarise across different types of variables with dplyr::c_across()
我有不同类型变量的数据。有些是字符,有些是因数,有些是数字,如下所示:
df <- data.frame(a = c("tt", "ss", "ss", NA), b=c(2,3,NA,1), c=c(1,2,NA, NA), d=c("tt", "ss", "ss", NA))
我正在尝试使用 dplyr
中的 c_across
计算每次观察的缺失值数量
但是,c_across
似乎无法组合不同类型的值,正如下面的错误消息所暗示的那样
df %>%
rowwise() %>%
summarise(NAs = sum(is.na(c_across())))
Error: Problem with summarise()
input NAs
.
x Can't combine a
<factor> and b
.
ℹ Input NAs
is sum(is.na(c_across()))
.
ℹ The error occurred in row 1.
的确,如果我只包含数字变量,它就可以工作。
df %>%
rowwise() %>%
summarise(NAs = sum(is.na(c_across(b:c))))
如果我只包含字符变量,同样如此
df %>%
rowwise() %>%
summarise(NAs = sum(is.na(c_across(c(a,d)))))
我可以不用像下面这样的 c_across
来解决这个问题,但是我有很多变量,所以不太实用。
df %>%
rowwise() %>%
summarise(NAs = is.na(a)+is.na(b)+is.na(c)+is.na(d))
我可以使用传统的 apply
方法,如下所示,但我想使用 dplyr
.
来解决这个问题
apply(df, 1, function(x)sum(is.na(x)))
关于如何高效地按行计算缺失值的数量以及使用 dplyr
的任何建议?
我建议采用这种方法。这个问题是因为两件事。首先,你的数据框中有不同类型的变量,然后你需要一个关键变量来完成按行样式的任务。因此,在接下来的代码中,我们首先将变量转换为类似的类型,然后我们根据行数创建一个 id。有了这个,我们将该元素用作 rowwise()
的输入,然后我们可以使用 c_across()
函数。代码在这里(我用过你df
数据):
library(tidyverse)
#Code
df %>%
mutate_at(vars(everything()),funs(as.character(.))) %>%
mutate(id=1:n()) %>%
rowwise(id) %>%
mutate(NAs = sum(is.na(c_across(a:d))))
输出:
# A tibble: 4 x 6
# Rowwise: id
a b c d id NAs
<chr> <chr> <chr> <chr> <int> <int>
1 tt 2 1 tt 1 0
2 ss 3 2 ss 2 0
3 ss NA NA ss 3 2
4 NA 1 NA NA 4 3
并且我们可以避免 mutate_at()
函数使用新的 across()
和 mutate()
来同源变量:
#Code 2
df %>%
mutate(across(a:d,~as.character(.))) %>%
mutate(id=1:n()) %>%
rowwise(id) %>%
mutate(NAs = sum(is.na(c_across(a:d))))
输出:
# A tibble: 4 x 6
# Rowwise: id
a b c d id NAs
<chr> <chr> <chr> <chr> <int> <int>
1 tt 2 1 tt 1 0
2 ss 3 2 ss 2 0
3 ss NA NA ss 3 2
4 NA 1 NA NA 4 3
一个更快的选择是不使用 rowwise
或 c_across
,而是使用 rowSums
library(dplyr)
df %>%
mutate(NAs = rowSums(is.na(.)))
# a b c d NAs
#1 tt 2 1 tt 0
#2 ss 3 2 ss 0
#3 ss NA NA ss 2
#4 <NA> 1 NA <NA> 3
如果我们想要 select
某些列,即 numeric
df %>%
mutate(NAs = rowSums(is.na(select(., where(is.numeric)))))
# a b c d NAs
#1 tt 2 1 tt 0
#2 ss 3 2 ss 0
#3 ss NA NA ss 2
#4 <NA> 1 NA <NA> 1
我有不同类型变量的数据。有些是字符,有些是因数,有些是数字,如下所示:
df <- data.frame(a = c("tt", "ss", "ss", NA), b=c(2,3,NA,1), c=c(1,2,NA, NA), d=c("tt", "ss", "ss", NA))
我正在尝试使用 dplyr
中的 c_across
计算每次观察的缺失值数量
但是,c_across
似乎无法组合不同类型的值,正如下面的错误消息所暗示的那样
df %>%
rowwise() %>%
summarise(NAs = sum(is.na(c_across())))
Error: Problem with
summarise()
inputNAs
. x Can't combinea
<factor> andb
. ℹ InputNAs
issum(is.na(c_across()))
. ℹ The error occurred in row 1.
的确,如果我只包含数字变量,它就可以工作。
df %>%
rowwise() %>%
summarise(NAs = sum(is.na(c_across(b:c))))
如果我只包含字符变量,同样如此
df %>%
rowwise() %>%
summarise(NAs = sum(is.na(c_across(c(a,d)))))
我可以不用像下面这样的 c_across
来解决这个问题,但是我有很多变量,所以不太实用。
df %>%
rowwise() %>%
summarise(NAs = is.na(a)+is.na(b)+is.na(c)+is.na(d))
我可以使用传统的 apply
方法,如下所示,但我想使用 dplyr
.
apply(df, 1, function(x)sum(is.na(x)))
关于如何高效地按行计算缺失值的数量以及使用 dplyr
的任何建议?
我建议采用这种方法。这个问题是因为两件事。首先,你的数据框中有不同类型的变量,然后你需要一个关键变量来完成按行样式的任务。因此,在接下来的代码中,我们首先将变量转换为类似的类型,然后我们根据行数创建一个 id。有了这个,我们将该元素用作 rowwise()
的输入,然后我们可以使用 c_across()
函数。代码在这里(我用过你df
数据):
library(tidyverse)
#Code
df %>%
mutate_at(vars(everything()),funs(as.character(.))) %>%
mutate(id=1:n()) %>%
rowwise(id) %>%
mutate(NAs = sum(is.na(c_across(a:d))))
输出:
# A tibble: 4 x 6
# Rowwise: id
a b c d id NAs
<chr> <chr> <chr> <chr> <int> <int>
1 tt 2 1 tt 1 0
2 ss 3 2 ss 2 0
3 ss NA NA ss 3 2
4 NA 1 NA NA 4 3
并且我们可以避免 mutate_at()
函数使用新的 across()
和 mutate()
来同源变量:
#Code 2
df %>%
mutate(across(a:d,~as.character(.))) %>%
mutate(id=1:n()) %>%
rowwise(id) %>%
mutate(NAs = sum(is.na(c_across(a:d))))
输出:
# A tibble: 4 x 6
# Rowwise: id
a b c d id NAs
<chr> <chr> <chr> <chr> <int> <int>
1 tt 2 1 tt 1 0
2 ss 3 2 ss 2 0
3 ss NA NA ss 3 2
4 NA 1 NA NA 4 3
一个更快的选择是不使用 rowwise
或 c_across
,而是使用 rowSums
library(dplyr)
df %>%
mutate(NAs = rowSums(is.na(.)))
# a b c d NAs
#1 tt 2 1 tt 0
#2 ss 3 2 ss 0
#3 ss NA NA ss 2
#4 <NA> 1 NA <NA> 3
如果我们想要 select
某些列,即 numeric
df %>%
mutate(NAs = rowSums(is.na(select(., where(is.numeric)))))
# a b c d NAs
#1 tt 2 1 tt 0
#2 ss 3 2 ss 0
#3 ss NA NA ss 2
#4 <NA> 1 NA <NA> 1