将零长度字符向量作为空字符串处理
Handling zero length character vectors as empty strings
例如,请参阅下面的 Twitter 句柄提取。目标是有一个类似于 tweets
的字符串,但只有用逗号分隔的句柄。 str_replace_all
在未找到匹配项时生成空向量,这会进一步引发一些意外错误。
library(purrr)
library(stringr)
tweets <- c(
"",
"This tweet has no handles",
"This is a tweet for @you",
"This is another tweet for @you and @me",
"This, @bla, is another tweet for @me and @you"
)
mention_rx <- "@\w+"
这是我的第一次尝试:
map_chr(tweets, ~str_c(str_extract_all(.x, mention_rx)[[1]], collapse = ", "))
#> Error: Result 1 must be a single string, not a character vector of length 0
然后我玩弄了一些东西:
mentions <- map(tweets, ~str_c(str_extract_all(.x, mention_rx)[[1]], collapse = ", "))
mentions
#> [[1]]
#> character(0)
#>
#> [[2]]
#> character(0)
#>
#> [[3]]
#> [1] "@you"
#>
#> [[4]]
#> [1] "@you, @me"
#>
#> [[5]]
#> [1] "@bla, @me, @you"
as.character(mentions)
#> [1] "character(0)" "character(0)" "@you" "@you, @me"
#> [5] "@bla, @me, @you"
直到我突然意识到 paste
也可以在这里使用:
map_chr(tweets, ~paste(str_extract_all(.x, mention_rx)[[1]], collapse = ", "))
#> "" "" "@you" "@you, @me" "@bla, @me, @you"
我的问题是:
- 有没有更优雅的方式到达那里?
- 为什么
str_c
的行为与具有相同 collapse
参数的 paste
的行为不同?
- 为什么
as.character
和 map_chr
不能识别字符向量
长度为零相当于一个空字符串,但是 paste
呢?
我在 , paste, and the 上找到了一些很好的参考资料;但是 none 其中解决了空字符串的情况。
您不需要map
超过tweets
,str_extract_all
可以处理向量
library(stringr)
str_extract_all(tweets, mention_rx)
#[[1]]
#character(0)
#[[2]]
#character(0)
#[[3]]
#[1] "@you"
#[[4]]
#[1] "@you" "@me"
#[[5]]
#[1] "@bla" "@me" "@you"
现在,如果您需要一个逗号分隔的字符串,那么您可以使用 map
purrr::map_chr(str_extract_all(tweets, mention_rx), toString)
#[1] "" "" "@you" "@you, @me" "@bla, @me, @you"
要回答"why"的问题,我们可以查看paste
和str_c
函数的文档。
来自?paste
Vector arguments are recycled as needed, with zero-length arguments being recycled to "".
来自 ?str_c
Zero length arguments are removed.
因此,默认情况下 str_c
删除零长度参数,这使得输出为 0 长度字符串,对于 map_chr
失败但它适用于 map
作为 map
returns 一个列表
map(tweets, ~str_c(str_extract_all(.x, mention_rx)[[1]], collapse = ", "))
#[[1]]
#character(0)
#[[2]]
#character(0)
#[[3]]
#[1] "@you"
#[[4]]
#[1] "@you, @me"
#[[5]]
#[1] "@bla, @me, @you"
例如,请参阅下面的 Twitter 句柄提取。目标是有一个类似于 tweets
的字符串,但只有用逗号分隔的句柄。 str_replace_all
在未找到匹配项时生成空向量,这会进一步引发一些意外错误。
library(purrr)
library(stringr)
tweets <- c(
"",
"This tweet has no handles",
"This is a tweet for @you",
"This is another tweet for @you and @me",
"This, @bla, is another tweet for @me and @you"
)
mention_rx <- "@\w+"
这是我的第一次尝试:
map_chr(tweets, ~str_c(str_extract_all(.x, mention_rx)[[1]], collapse = ", "))
#> Error: Result 1 must be a single string, not a character vector of length 0
然后我玩弄了一些东西:
mentions <- map(tweets, ~str_c(str_extract_all(.x, mention_rx)[[1]], collapse = ", "))
mentions
#> [[1]]
#> character(0)
#>
#> [[2]]
#> character(0)
#>
#> [[3]]
#> [1] "@you"
#>
#> [[4]]
#> [1] "@you, @me"
#>
#> [[5]]
#> [1] "@bla, @me, @you"
as.character(mentions)
#> [1] "character(0)" "character(0)" "@you" "@you, @me"
#> [5] "@bla, @me, @you"
直到我突然意识到 paste
也可以在这里使用:
map_chr(tweets, ~paste(str_extract_all(.x, mention_rx)[[1]], collapse = ", "))
#> "" "" "@you" "@you, @me" "@bla, @me, @you"
我的问题是:
- 有没有更优雅的方式到达那里?
- 为什么
str_c
的行为与具有相同collapse
参数的paste
的行为不同? - 为什么
as.character
和map_chr
不能识别字符向量 长度为零相当于一个空字符串,但是paste
呢?
我在
您不需要map
超过tweets
,str_extract_all
可以处理向量
library(stringr)
str_extract_all(tweets, mention_rx)
#[[1]]
#character(0)
#[[2]]
#character(0)
#[[3]]
#[1] "@you"
#[[4]]
#[1] "@you" "@me"
#[[5]]
#[1] "@bla" "@me" "@you"
现在,如果您需要一个逗号分隔的字符串,那么您可以使用 map
purrr::map_chr(str_extract_all(tweets, mention_rx), toString)
#[1] "" "" "@you" "@you, @me" "@bla, @me, @you"
要回答"why"的问题,我们可以查看paste
和str_c
函数的文档。
来自?paste
Vector arguments are recycled as needed, with zero-length arguments being recycled to "".
来自 ?str_c
Zero length arguments are removed.
因此,默认情况下 str_c
删除零长度参数,这使得输出为 0 长度字符串,对于 map_chr
失败但它适用于 map
作为 map
returns 一个列表
map(tweets, ~str_c(str_extract_all(.x, mention_rx)[[1]], collapse = ", "))
#[[1]]
#character(0)
#[[2]]
#character(0)
#[[3]]
#[1] "@you"
#[[4]]
#[1] "@you, @me"
#[[5]]
#[1] "@bla, @me, @you"