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

前端 未结 2 1347
暖寄归人
暖寄归人 2021-01-13 15:07

When I apply across columns in this example I get a white space for positive valued numbers but not for negative values? Why is this? Shouldn\'t paste0 remove whitespace be

相关标签:
2条回答
  • 2021-01-13 15:46

    Since you are already using dplyr, a dplyr solution is to use

    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
    

    Using a tibble instead of a data.frame by default will not convert your vector to a factor, which I think is desirable in this instance.

    Additionally, regarding your question about paste0, it does not remove whitespace between words, it just doesn't add them when concatenating. str_trim in the stringr package will trim whitespace for you.

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

    Will also provide the desired result.

    0 讨论(0)
  • 2021-01-13 16:08

    Why does the white space show up?

    paste0 doesn't add white space - nor does it remove it. You can test this by just calling paste0 on your vector.

    apply runs on matrices and arrays, not data frames. When you pass a data frame to apply, it is coerced to a matrix. The main thing about a matrix, of course, is that all elements must be the same type. Since strings or factors can't generally be coerced to numerics, your numeric is coerced to a string or factor to match the first column. If you examine as.matrix.data.frame, you'll see that format is used for this conversion, and ?format shows a default trim = FALSE that says

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

    So there's your problem!


    What's the solution?

    paste and paste0 are vectorized, so there's no reason to apply them one row at a time. You can just paste the columns together directly:

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

    In a more complicated case where apply really would be necessary, the solution would be to handle your own matrix conversion rather than relying on apply to do it with defaults. If you made all the columns strings before passing the data to apply, (or if you used a character matrix instead of a data frame), the conversion would be straightforward (or unnecessary).

    0 讨论(0)
提交回复
热议问题