【问题标题】:Why does apply(x, 1, paste0(collapse="") leave white space between positive values?为什么 apply(x, 1, paste0(collapse="") 在正值之间留下空白?
【发布时间】:2016-08-02 22:17:04
【问题描述】:

当我在此示例中跨列应用时,我得到一个用于正值的空格,但不是用于负值?为什么是这样? paste0 不应该删除元素之间的空格吗?这个问题背后的背景是我正在尝试为 googlemaps Directions 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")) 

编辑:我认为这与在具有不同数据类型的数据帧上运行应用程序有关(lat 是字符,lon 是数字)

【问题讨论】:

  • 为什么要逐行使用collapse 参数? with(stop_latlon, paste0(lat, "%7", lon)) 不是你要找的吗?
  • 是的。这就是我要找的。谢谢!
  • 请注意将applydata.frame 一起使用而不是lapply。详解stackoverflow.com/a/37828523/3817004
  • 你拿了一个衬里,用一根管子做了两个。也许我只是还没有得到管道......
  • 我已经编写了 googleway 包,如果它能让你的生活更轻松,你可以使用它来访问 Google Maps API(在你的情况下是函数 google_directions()

标签: r dataframe apply


【解决方案1】:

为什么会出现空白?

paste0 不会添加空格 - 也不会删除它。你可以通过在你的向量上调用paste0来测试它。

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

trim;如果FALSE,逻辑值、数字值和复数值右对齐到一个公共宽度:如果TRUE 用于对齐的前导空格被抑制。

所以你的问题来了!


解决办法是什么?

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

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

在真正需要apply 的更复杂的情况下,解决方案是处理您自己的矩阵转换,而不是依靠apply 来使用默认值。如果您将数据传递给apply(或者如果您使用字符矩阵而不是数据框)创建了所有列字符串,则转换将很简单(或不必要)。 p>

【讨论】:

    【解决方案2】:

    由于您已经在使用 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 将为您修剪空白。

    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")) 
    

    还将提供所需的结果。

    【讨论】:

    • 转换为因子不会导致错误。问题出在 apply 内部发生的字符串转换。该行被转换为字符向量,并且转换包括正数的空格
    • 我认为这最后的评论应该是我的问题?
    • @Carton,正确。我知道这不会导致这个问题。我只是认为方向不是真正的因素,它们是字符串。
    • @Gregor 您对 OP 问题“为什么”的回答可能是一个很好的答案。
    • 为什么要加载另一个包来修剪空白?它在基地。 trimws
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2021-09-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多