如何逐行删除数据帧中的 NA 变量
How to drop NA variables in a data frame by row
这是我的数据框:
structure(list(Q = c(NA, 346.86, 166.95, 162.57, NA, NA, NA,
266.7), L = c(18.93, NA, 15.72, 39.51, NA, NA, NA, NA), C = c(NA,
23.8, NA, 8.47, 20.89, 18.72, 14.94, NA), X = c(40.56, NA, 26.05,
3.08, 23.77, 59.37, NA, NA), W = c(29.47, NA, NA, NA, 36.08,
NA, 27.34, 28.19), S = c(NA, 7.47, NA, NA, 18.64, NA, 25.34,
NA), Y = c(NA, 2.81, 0, NA, NA, 21.18, 10.83, 12.19), H = c(0,
NA, NA, NA, NA, 0, NA, 0)), class = "data.frame", row.names = c(NA,
-8L), .Names = c("Q", "L", "C", "X", "W", "S", "Y", "H"))
每一行有4个NA变量,现在我想对每一行做同样的操作:
- 删除 NA 的那 4 个变量
- 计算其余4个变量的多样性(这只是涉及其余部分的一些计算,这里我使用
vegan
中的diversity()
)
- 将输出附加到新的数据框
但问题是:
- 如何使用
dplyr
删除 NA 变量?不知道select()
能不能来得及
- 如何对数据框的每一行应用操作?
drop_na()
似乎会删除我的数据集的整行,有什么建议吗?
对于 tidyverse
,最好将 gather
转换为 'long' 格式,然后 spread
返回。假设我们每行正好有 4 个非 NA 元素,创建一个行索引 rownames_to_column
(从 tibble
),gather
(从 tidyr
)到 'long' 格式,删除 NA 元素,按行号分组 ('rn'),将 'key' 值更改为常用值,然后 spread
将其更改为宽格式
library(tibble)
library(tidyr)
library(dplyr)
res <- rownames_to_column(df1, 'rn') %>%
gather(key, val, -rn) %>%
filter(!is.na(val)) %>%
group_by(rn) %>%
mutate(key = LETTERS[1:4]) %>%
spread(key, val) %>%
ungroup %>%
select(-rn)
res
# A tibble: 8 x 4
# A B C D
#* <dbl> <dbl> <dbl> <dbl>
#1 18.9 40.6 29.5 0
#2 347 23.8 7.47 2.81
#3 167 15.7 26.0 0
#4 163 39.5 8.47 3.08
#5 20.9 23.8 36.1 18.6
#6 18.7 59.4 21.2 0
#7 14.9 27.3 25.3 10.8
#8 267 28.2 12.2 0
diversity(res)
# 1 2 3 4 5 6 7 8
#1.0533711 0.3718959 0.6331070 0.7090783 1.3517680 0.9516232 1.3215712 0.4697572
关于 diversity
计算,我们可以 replace
NA 为 0 并应用于整个数据集,即
library(vegan)
diversity(replace(df1, is.na(df1), 0))
#[1] 1.0533711 0.3718959 0.6331070 0.7090783
#[5] 1.3517680 0.9516232 1.3215712 0.4697572
因为我们得到与第一个解决方案相同的输出
这是我的数据框:
structure(list(Q = c(NA, 346.86, 166.95, 162.57, NA, NA, NA,
266.7), L = c(18.93, NA, 15.72, 39.51, NA, NA, NA, NA), C = c(NA,
23.8, NA, 8.47, 20.89, 18.72, 14.94, NA), X = c(40.56, NA, 26.05,
3.08, 23.77, 59.37, NA, NA), W = c(29.47, NA, NA, NA, 36.08,
NA, 27.34, 28.19), S = c(NA, 7.47, NA, NA, 18.64, NA, 25.34,
NA), Y = c(NA, 2.81, 0, NA, NA, 21.18, 10.83, 12.19), H = c(0,
NA, NA, NA, NA, 0, NA, 0)), class = "data.frame", row.names = c(NA,
-8L), .Names = c("Q", "L", "C", "X", "W", "S", "Y", "H"))
每一行有4个NA变量,现在我想对每一行做同样的操作:
- 删除 NA 的那 4 个变量
- 计算其余4个变量的多样性(这只是涉及其余部分的一些计算,这里我使用
vegan
中的diversity()
) - 将输出附加到新的数据框
但问题是:
- 如何使用
dplyr
删除 NA 变量?不知道select()
能不能来得及 - 如何对数据框的每一行应用操作?
drop_na()
似乎会删除我的数据集的整行,有什么建议吗?
对于 tidyverse
,最好将 gather
转换为 'long' 格式,然后 spread
返回。假设我们每行正好有 4 个非 NA 元素,创建一个行索引 rownames_to_column
(从 tibble
),gather
(从 tidyr
)到 'long' 格式,删除 NA 元素,按行号分组 ('rn'),将 'key' 值更改为常用值,然后 spread
将其更改为宽格式
library(tibble)
library(tidyr)
library(dplyr)
res <- rownames_to_column(df1, 'rn') %>%
gather(key, val, -rn) %>%
filter(!is.na(val)) %>%
group_by(rn) %>%
mutate(key = LETTERS[1:4]) %>%
spread(key, val) %>%
ungroup %>%
select(-rn)
res
# A tibble: 8 x 4
# A B C D
#* <dbl> <dbl> <dbl> <dbl>
#1 18.9 40.6 29.5 0
#2 347 23.8 7.47 2.81
#3 167 15.7 26.0 0
#4 163 39.5 8.47 3.08
#5 20.9 23.8 36.1 18.6
#6 18.7 59.4 21.2 0
#7 14.9 27.3 25.3 10.8
#8 267 28.2 12.2 0
diversity(res)
# 1 2 3 4 5 6 7 8
#1.0533711 0.3718959 0.6331070 0.7090783 1.3517680 0.9516232 1.3215712 0.4697572
关于 diversity
计算,我们可以 replace
NA 为 0 并应用于整个数据集,即
library(vegan)
diversity(replace(df1, is.na(df1), 0))
#[1] 1.0533711 0.3718959 0.6331070 0.7090783
#[5] 1.3517680 0.9516232 1.3215712 0.4697572
因为我们得到与第一个解决方案相同的输出