【发布时间】:2021-12-20 04:12:32
【问题描述】:
我有一个很长的数据框,里面有很多NA。
我想求 A 列和 D 列的值的比率。 如何只选择 A 列和 D 列中都存在数据的行?
例如,在这张图片中,我只想比较 A 列和 D 列的第 2、4、6 行的值。
我可以在每一行上使用na.omit,但我不确定如何让 R 找到两列中都存在数据的行。
【问题讨论】:
我有一个很长的数据框,里面有很多NA。
我想求 A 列和 D 列的值的比率。 如何只选择 A 列和 D 列中都存在数据的行?
例如,在这张图片中,我只想比较 A 列和 D 列的第 2、4、6 行的值。
我可以在每一行上使用na.omit,但我不确定如何让 R 找到两列中都存在数据的行。
【问题讨论】:
像这样:
library(tidyverse)
df <- data.frame(col1=c(1, NA, 7), col2=c(NA, 2, 5))
# col1 col2
# 1 1 NA
# 2 NA 2
# 3 7 5
df %>%
filter(!is.na(col1) & !is.na(col2))
#
# col1 col2
# 1 7 5
【讨论】:
df %>% drop_na(A, D)(来自 tidyr 的跟踪者)。
filter(df, complete.cases(A, D)),因为当我看到 drop 时,我想到的是删除列而不是过滤值,但其中大部分是偏好。
以下是一些使用 base R.
的选项使用is.na():
df[!is.na(df$A) & !is.na(df$D), ]
# A B C D
# 1 432 15 54654 432
# 2 321 NA 4534 324
# 3 123 432 6543 75
使用complete.cases():
df[complete.cases(df$A, df$D), ]
# A B C D
# 1 432 15 54654 432
# 2 321 NA 4534 324
# 3 123 432 6543 75
使用subset():
subset(df, complete.cases(A, D))
# A B C D
# 1 432 15 54654 432
# 2 321 NA 4534 324
# 3 123 432 6543 75
以下是使用 tidyverse 的其他几个选项。
使用来自tidyr的drop_na():
library(dplyr)
library(tidyr)
df %>%
drop_na(A, D)
# A B C D
# 1 432 15 54654 432
# 2 321 NA 4534 324
# 3 123 432 6543 75
在dplyr 中使用complete.cases() 和filter()(这实际上是我对可读性的偏好):
library(dplyr)
df %>%
filter(complete.cases(A, D))
# A B C D
# 1 432 15 54654 432
# 2 321 NA 4534 324
# 3 123 432 6543 75
数据:
df <- data.frame(A = c(23, 432, NA, 321, NA, 123),
B = c(NA, 15, NA, NA, 32, 432),
C = c(NA, 54654, NA, 4534, NA, 6543),
D = c(NA, 432, 654, 324, 643, 75))
【讨论】:
只获取你可以简单的值:
(df$A / df$D)[!is.na(df$A / df$D)]
[1] 1.0000000 0.9907407 1.6400000
这会将值作为附加列:
cbind( df, df$A / df$D )
A B C D df$A/df$D
1 23 NA NA NA NA
2 432 15 54654 432 1.0000000
3 NA NA NA 654 NA
4 321 NA 4534 324 0.9907407
5 NA 32 NA 643 NA
6 123 432 6543 75 1.6400000
【讨论】: