lapply & sapply on data.frame 测试每列中的所有元素以获得单个逻辑
lapply & sapply on data.frame to test all elements in each column to get a single logical
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
lapply 结果:
$dates1
[1] FALSE FALSE FALSE
$dates2
[1] FALSE FALSE FALSE
WTH是怎么回事??
写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
首先请注意,代码的问题在于操作顺序。 %>%
在 ==
之前执行,但我们希望 ==
在最后一个 %>%
之前执行,因此使用括号强制执行此操作。这里显示的最里面的括号实际上是不需要的,因为默认的操作顺序已经适用于那些;但是,除了为清楚起见所需的内容之外,我们还添加了它们。请参阅 ?Syntax
以获得完整的 table 给出的操作顺序。
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
另一种摆脱循环的方法是使用 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
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
lapply 结果:
$dates1
[1] FALSE FALSE FALSE
$dates2
[1] FALSE FALSE FALSE
WTH是怎么回事??
写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
首先请注意,代码的问题在于操作顺序。 %>%
在 ==
之前执行,但我们希望 ==
在最后一个 %>%
之前执行,因此使用括号强制执行此操作。这里显示的最里面的括号实际上是不需要的,因为默认的操作顺序已经适用于那些;但是,除了为清楚起见所需的内容之外,我们还添加了它们。请参阅 ?Syntax
以获得完整的 table 给出的操作顺序。
sapply(df,function(x) ((x %>% na.omit %>% as.character %>% nchar) == 8) %>% all)
## dates1 dates2
## TRUE FALSE
但是,使用以下事实可能会更好:
nchar
已经将其参数强制转换为字符,因此我们可以消除as.character
. %>% whatever
可用于定义一个函数 wjerewhatever
被替换为假设单个参数为点 (.) 的函数体
{...}
可用于防止自动 .插入:
给予:
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
另一种摆脱循环的方法是使用 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