为什么 apply(x, 1, paste0(collapse="") 在正值之间留下白色 space?

Why does apply(x, 1, paste0(collapse="") leave white space between positive values?

当我在这个例子中跨列应用时,我得到一个白色 space 表示正值而不是负值?为什么是这样?不应该 paste0 删除元素之间的 whitespace 吗?这个问题背后的背景是我正在尝试为 googlemaps 方向 api 形成端点。

library(dplyr)
stop_latlon <- data.frame(lat = paste0("via:", rnorm(10)), lon = rnorm(10))

stop_latlon %>% 
  apply(1, function(x) paste0(x, collapse = "%7")) 

编辑:我认为它与 运行 apply on a dataframe with different data types (lat is a character and lon is a numeric)

由于您已经在使用 dplyr,因此 dplyr 解决方案是使用

stop_latlon %>% rowwise() %>% 
  summarise(latlon = paste0(lat, "%7", lon))

# A tibble: 10 x 1
                                       latlon
                                        <chr>
1     via:1.222988975822%7-0.0916195541513781
2     via:0.159343465931011%72.13195314768885
3    via:-1.20468509249113%70.207717129395512
4  via:-0.134019685121819%7-0.912028913867691
5    via:-0.279895116522155%71.93812564387851
6     via:1.34379237820276%70.500525410068601
7   via:0.808272181619927%7-0.942578996972991
8    via:-1.17359899808855%70.126116638988962
9      via:1.1859602145711%7-1.00865269561505
10    via:1.77635906904826%70.685722866041471

默认情况下使用 tibble 而不是 data.frame 不会将向量转换为因子,我认为在这种情况下这是可取的。

此外,关于您关于 paste0 的问题,它不会删除单词之间的空格,只是在连接时不会添加它们。 stringr 包中的 str_trim 将为您提供 trim 空格。

stop_latlon <- data.frame(lat = paste0("via:", rnorm(10)),
                          lon = rnorm(10), stringsAsFactors = FALSE)


library(stringr)
stop_latlon %>% 
  apply(1, function(x) paste0(str_trim(x), collapse = "%7")) 

也将提供所需的结果。

为什么会出现白色 space?

paste0 不会添加白色 space - 也不会删除它。您可以通过在向量上调用 paste0 来测试它。

apply 在矩阵和数组上运行,而不是数据帧。当您将数据框传递给 apply 时,它会被强制转换为矩阵。当然,关于矩阵的主要内容是所有元素必须是同一类型。由于字符串或因子通常不能被强制转换为数字,因此您的数字会被强制转换为字符串或因子以匹配第一列。如果您检查 as.matrix.data.frame,您会看到 format 用于此转换,而 ?format 显示默认 trim = FALSE

trim; if FALSE, logical, numeric and complex values are right-justified to a common width: if TRUE the leading blanks for justification are suppressed.

你的问题来了!


有什么解决办法?

pastepaste0 是向量化的,因此没有理由一次 apply 它们一行。您可以直接将列粘贴在一起:

with(stop_latlon, paste0(lat, "%7", lon))

在确实需要 apply 的更复杂的情况下,解决方案是处理您自己的矩阵转换,而不是依赖 apply 使用默认值进行转换。如果在 将数据传递给 apply 之前将所有列设为字符串 ,(或者如果您使用字符矩阵而不是数据框),转换将很简单(或不必要)。