lapply & sapply на data.frame для тестирования всех элементов в каждом столбце, чтобы получить единый логический - PullRequest
0 голосов
/ 29 июня 2018
library(tidyverse)
df = data.frame(dates1 = c(20120631,NA,20130504,20161211),
                dates2 = c(201604,201503,NA,201201))
sapply(df,function(x) x %>% na.omit %>% as.character %>% nchar==8 %>% all)
lapply(df,function(x) x %>% na.omit %>% as.character %>% nchar==8 %>% all)
sapply(df,function(x) x %>% na.omit %>% as.character %>% nchar==8 %>% any)
lapply(df,function(x) x %>% na.omit %>% as.character %>% nchar==8 %>% any)

Если у меня есть какая-либо подсказка о том, как sapply & lapply работает (и я почти уверен, что это сработало вчера), это должно вернуть мне один TRUE или FALSE. Это не. Я возвращаю матрицу истинного и ложного. Это не то, что any() или all() должен делать.

Результаты поиска:

     dates1 dates2
[1,]  FALSE  FALSE
[2,]  FALSE  FALSE
[3,]  FALSE  FALSE

счастливые результаты:

$dates1
[1] FALSE FALSE FALSE

$dates2
[1] FALSE FALSE FALSE

WTH продолжается ??

Ответы [ 3 ]

0 голосов
/ 29 июня 2018

Прежде всего обратите внимание, что проблема с кодом - это порядок операций. %>% выполняется до ==, но мы хотим, чтобы == выполнялось до последнего %>%, поэтому используйте скобки, чтобы форсировать это. Внутренние скобки, показанные здесь, на самом деле не нужны, поскольку порядок операций по умолчанию для них уже работает; однако мы добавили их в дополнение к тем, которые необходимы для ясности. См. ?Syntax для полной таблицы, в которой указан порядок операций.

sapply(df,function(x) ((x %>% na.omit %>% as.character %>% nchar) == 8) %>% all)
## dates1 dates2 
##   TRUE  FALSE 

однако, это может быть лучше написано следующим образом, используя факты, которые:

  • nchar уже приводит свой аргумент к символу, поэтому мы можем исключить as.character
  • . %>% whatever может использоваться для определения функции wjere whatever заменяется телом функции, предполагая, что единственным аргументом является точка (.)
  • {...} может использоваться для предотвращения автоматического. Вставка:

дает:

df %>% sapply(. %>% na.omit %>% { nchar(.) == 8 } %>% all)
## dates1 dates2 
##   TRUE  FALSE 

или, если то, что нужно, это одна логика для всех столбцов, то:

p <- df %>% sapply(na.omit) %>% { nchar(.) == 8 } 

p %>% all
## [1] FALSE

p %>% any
## [1] TRUE
0 голосов
/ 30 июня 2018

Еще один способ избавиться от циклов - использовать векторизованную природу nchar

 p <- colMeans(nchar(as.matrix(df)),na.rm = T)==8
 any(p)
[1] TRUE
 all(p)
[1] FALSE

или используя трубопровод:

p<- df %>% as.matrix %>% nchar %>% colMeans(na.rm = T) %>% {. == 8}

p %>% any
[1] TRUE

 p %>% all
[1] FALSE
0 голосов
/ 29 июня 2018

Запись x %>% nchar == 8 %>% any эквивалентна nchar(x) == any(8), и поэтому не будет такой же, как any(nchar(x) == 8)

Я думаю, это то, что вы ищете

sapply(df,function(x) x %>% na.omit %>% as.character %>% (function(x) nchar(x) == 8) %>% all)
# dates1 dates2 
#   TRUE  FALSE 
sapply(df,function(x) x %>% na.omit %>% as.character %>% (function(x) nchar(x) == 8) %>% any)
# dates1 dates2 
#   TRUE  FALSE

Эквивалентное:

sapply(df,function(x) x %>% na.omit %>% as.character %>% nchar %>% `==`(8) %>% all)
# dates1 dates2 
#   TRUE  FALSE 
sapply(df,function(x) x %>% na.omit %>% as.character %>% nchar %>% `==`(8) %>% any)
# dates1 dates2 
#   TRUE  FALSE
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...