#r #dataframe
#r #dataframe
Вопрос:
Мне интересно, какой наиболее эффективный способ проверить, содержит ли фрейм погодных данных только 1 или 0 или нет. Я бы сказал, что мне пришла в голову очень интуитивная, но неэффективная идея.
Моя идея
Заключается в преобразовании всего фрейма данных в вектор. Затем проверьте, равна ли длина этого вектора сумме длин всех столбцов с условиями == 0 или ==1.
Пример
> df<-data.frame(sample(0:1,10,replace=T),sample(0:1,10,replace=T),sample(0:1,10,replace=T))
> df
sample.0.1..10..replace...T. sample.0.1..10..replace...T..1 sample.0.1..10..replace...T..2
1 0 1 1
2 0 0 1
3 1 1 0
4 0 0 0
5 1 0 1
6 0 0 0
7 1 0 0
8 0 0 0
9 0 1 0
10 1 0 1
length(unlist(df,use.names=F))
30
length(df[,1][df[,1]==0]) length(df[,1][df[,1]==1]) length(df[,2][df[,2]==0]) length(df[,2]
[df[,2]==1]) length(df[,3][df[,3]==0]) length(df[,3][df[,3]==1])
30
Есть ли более быстрый способ, как это сделать?
Комментарии:
1. Почему это data.frame, а не матрица? Вы могли бы просто сделать
all(as.matrix(df) %in% 0:1)
. (Я предполагаю, что значения данных были импортированы и не являются вычисляемыми числами с плавающей запятой.)2.
all(unlist(df) %in% c(0, 1))
аall(df == 0 | df == 1)
также работает.
Ответ №1:
Обычно я бы пошел на
all(sapply(df, function(x) all(x) %in% c(0,1)))
[1] TRUE
Однако вы должны знать, что R принудительно преобразует логические значения в числовые при оценке этих условий. Это может привести к возврату TRUE
даже для логических значений. Например, предыдущий оператор возвращает TRUE
для
test <- c(TRUE, TRUE, FALSE)
Поэтому это решение необходимо изменить, чтобы проверить числовые значения, которые вам нужны.
all(sapply(test, function(x) is.numeric(x) amp; all(x) %in% c(0,1)))
[1] FALSE
all(sapply(df, function(x) is.numeric(x) amp; all(x) %in% c(0,1)))
[1] TRUE
РЕДАКТИРОВАТЬ: он также работает с данными, которые включают NA
‘s, с предупреждением.
df_missing <- df
df_missing$nacol <- c(rep(1,9),NA)
all(sapply(df_missing, function(x) is.numeric(x) amp; all(x) %in% c(0,1)))
[1] FALSE
Warning message:
In all(x) : coercing argument of type 'double' to logical
Ответ №2:
Вы могли бы перейти к table
функции и проверить, есть ли all
names
%in% 0:1
они. Если вы хотите учесть пропущенный аргумент use use.na=
, опустите его в противном случае.
Вот как это выглядит:
table(unlist(dat.m), useNA="ifany")
# 0 1 <NA>
# 52 73 10
В действии:
all(names(table(unlist(dat), useNA="ifany")) %in% 0:1)
# [1] TRUE
all(names(table(unlist(dat.m), useNA="ifany")) %in% 0:1)
# [1] FALSE
all(names(table(unlist(dat.99), useNA="ifany")) %in% 0:1)
# [1] FALSE
Данные:
m <- 15;n <- 9
set.seed(42)
M <- matrix(rbinom(m*n, 1, .5), m, n)
## clean
dat <- as.data.frame(M)
## with missings
M[as.logical(rbinom(length(M), 1, .1))] <- NA
dat.na <- as.data.frame(M)
## with other numbers
M[as.logical(rbinom(length(M), 1, .1))] <- -99
dat.99 <- as.data.frame(M)