Как использовать apply или vapply в столбце набора данных с функцией нескольких параметров - PullRequest
0 голосов
/ 13 мая 2019

Мой набор данных называется данными, и у меня есть столбец с именем time, который содержит время в формате mm: ss. Я также написал функцию functime (var1, var2).

В конечном счете, я хотел бы использовать apply или vapply и установить для var2 постоянную (скажем, var2 = 6), а var1 - для каждого значения данных столбца $ time.

Что-то вроде:

Если

data$time <- c("10:10","11:00", "09:30"), when I do vapply(), I would like to get a 

data$output <-c(functime(data$time[1],6),functime(data$time[2],6),functime(data$time[3],6))

, который в этом примере совпадает с

data$output <- c(functime("10:10",6),functime("11:00",6),functime("09:30",6))

Моя неудачная попытка это что-то вроде:

vapply(data$time,functime,var2 = 6,FUN.VALUE = 1)

Документация для vapply гласит: vapply (x, fun, fun.value)

Я запутался в том, как "сказать vapply", что я хочу принять в качестве первого аргумента все строки столбца данных $ time, у меня есть фиксированный второй аргумент, который я определю как 6.

В конечном итоге я хотел бы добавить свои выходные данные $ в исходный набор данных, используя mutate.

Изменить: (Включить строки данных и функции)

data$id <- c(9,6,5763,4)

data$time <- c("5:06","5:06","5:11","5:08")

data$city <-c("Kyle","Oklahoma","Monterey","Austin")

Функция:

    calctime <- function(racePace, raceDistance){

  # racePace is the per unit pace in mm:ss - character
  # raceDistance is the total race distance - numeric
  # Pace and race distance must use same units (km or mi or whatever)

  # Seconds to character time function
  CharMinSec <- function(sec){
    outMin <- floor(sec/60)
   outSec <- ((sec/60)-outMin)*60
    if(outSec==0 | round(outSec)<10){
      outChar <- paste0(outMin,":0",round(outSec))
    } else {
      outChar <- paste(outMin,round(outSec),sep=":")
    }
    outChar
  }

  paceMinSec <- as.numeric(strsplit(racePace,':')[[1]])
  paceSec <- paceMinSec[1]*60+ paceMinSec[2]
  raceMin <- floor(paceSec*raceDistance/60)
  raceSec <- ((paceSec*raceDistance/60)-raceMin)*60
  raceTime <- CharMinSec(raceMin*60+raceSec)
  list(Seconds=raceSec)
}

# Example of 4:15/km for a half-marathon


calctime("4:15",21.097494)

Ответы [ 2 ]

2 голосов
/ 14 мая 2019

calcTime <- function(pace,distance){ 
  return (lubridate::period_to_seconds(lubridate::ms(pace)) * distance)
}


pace <- c("10:10","11:00", "09:30")
vapply(pace,calcTime,6,FUN.VALUE = 1)

## 10:10 11:00 09:30 
## 36960 39960 34560 

d <- tibble::as_tibble(list(pace = pace))
dplyr::mutate(d, raceSeconds = calcTime(pace,6))

## A tibble: 3 x 2
##    pace   raceSeconds
##    <chr>  <dbl>
##  1 10:10  36960
##  2 11:00  39960
##  3 09:30  34560

1 голос
/ 14 мая 2019

Мне пришлось изменить 2 вещи, но ваш vapply звонок был верным.

В функции я изменил последнюю строку, чтобы она возвращала значение вместо списка с одним значением

calctime <- function(racePace, raceDistance){

  # racePace is the per unit pace in mm:ss - character
  # raceDistance is the total race distance - numeric
  # Pace and race distance must use same units (km or mi or whatever)

  # Seconds to character time function
  CharMinSec <- function(sec){
    outMin <- floor(sec/60)
    outSec <- ((sec/60)-outMin)*60
    if(outSec==0 | round(outSec)<10){
      outChar <- paste0(outMin,":0",round(outSec))
    } else {
      outChar <- paste(outMin,round(outSec),sep=":")
    }
    outChar
  }

  paceMinSec <- as.numeric(strsplit(racePace,':')[[1]])
  paceSec <- paceMinSec[1]*60+ paceMinSec[2]
  raceMin <- floor(paceSec*raceDistance/60)
  raceSec <- ((paceSec*raceDistance/60)-raceMin)*60
  raceTime <- CharMinSec(raceMin*60+raceSec)
  raceSec
}

Теперь, когда список возвращает значение, vapply() работает, но в моем случае мне пришлось заставить столбец времени быть символом

data = data.frame(
  id = c(9,6,5763,4),
  time = c("5:06","5:06","5:11","5:08"),
  city = c("Kyle","Oklahoma","Monterey","Austin")
)

data$time = as.character(data$time)

data$output = vapply(data$time,calctime,raceDistance = 6,FUN.VALUE=1) #works fine
...