Если входные номера всегда содержат 7 или 8 цифр, вы также можете использовать
$str = ($input < 10000000) ? 0 . $input : $input;
Я провел несколько тестов и понял, что это будет удвоено так же быстро, как str_pad
или sprintf
. Если вход может иметь любую длину, вы также можете использовать
$str = substr('00000000' . $input, -8);
. Это не так быстро, как у другого, но также должно быть немного быстрее, чем str_pad
и sprintf
.
Btw: Мой тест также сказал, что sprintf
немного быстрее, чем str_pad
. Я сделал все тесты с PHP 5.6.
Вы можете переписать свой код с помощью mutate_at
, чтобы преобразование можно было сделать за один раз, как:
library(dplyr)
library(zoo)
df %>%
group_by(iso) %>%
mutate_at(vars(starts_with("var")),
funs(na.locf(na.locf(na.approx(., na.rm = FALSE, rule = 1),na.rm=FALSE),
fromLast=TRUE)))
# # A tibble: 6 x 5
# # Groups: iso [2]
# iso year var1 var2 var3
# <chr> <int> <dbl> <dbl> <dbl>
# 1 XXX 2005 165 29.0 2151
# 2 XXX 2006 160 21.0 2139
# 3 XXX 2007 172 15.0 2890
# 4 XXX 2008 184 9.00 3640
# 5 XXX 2009 184 9.00 3640
# 6 YYY 2005 206 461 8049
#
Данные:
df <- read.table(text=
"iso year var1 var2 var3
1 XXX 2005 165 29 2151
2 XXX 2006 160 21 2139
3 XXX 2007 NA NA NA
4 XXX 2008 184 9 3640
5 XXX 2009 NA NA NA
6 YYY 2005 206 461 8049",
header = TRUE, stringsAsFactors = FALSE)
Используйте na.approx
с method = "constant"
(так же, как na.locf
) и rule = 2
(это означает, что ближайшее приближение к ведущим и конечным NA). Если вы хотите, чтобы NAs были линейно интерполированы, удалите аргумент method="constant"
.
df1 %>%
group_by(iso) %>%
mutate_at(vars(-iso), funs(na.approx(., method = "constant", rule = 2))) %>%
ungroup
, давая:
# A tibble: 6 x 5
iso year var1 var2 var3
<fct> <dbl> <dbl> <dbl> <dbl>
1 XXX 2005 165 29 2151
2 XXX 2006 160 21 2139
3 XXX 2007 160 21 2139
4 XXX 2008 184 9 3640
5 XXX 2009 184 9 3640
6 YYY 2005 206 461 8049
df1
в воспроизводимой форме:
df1 <-
structure(list(iso = structure(c(1L, 1L, 1L, 1L, 1L, 2L), .Label = c("XXX",
"YYY"), class = "factor"), year = c(2005L, 2006L, 2007L, 2008L,
2009L, 2005L), var1 = c(165L, 160L, NA, 184L, NA, 206L), var2 = c(29L,
21L, NA, 9L, NA, 461L), var3 = c(2151L, 2139L, NA, 3640L, NA,
8049L)), class = "data.frame", row.names = c("1", "2", "3", "4",
"5", "6"))
XXX
в среднем за 2006 и 2008 годы, но применяет данные за 2008 год к 2009 году?
– Alexander91
14 July 2018 в 15:56
method="constant"
, оно работает как na.locf
. Он заполняет НС самым последним предыдущим не-NA, как na.locf
, но также он заполняет ведущие NA с первым не-NA. Я добавил результат в ответ. Посмотрите на ?na.approx
, а для аргументов method
и rule
смотрите ?approx
.
– G. Grothendieck
14 July 2018 в 16:26
na.locf
, предполагая, что эта функция была тем, что вы хотели использовать. но если вы хотите, чтобы линейная интерполяция окружающих точек удаляла аргумент method = "constant"
, по умолчанию для na.approx
используется линейная интерполяция.
– G. Grothendieck
14 July 2018 в 16:34
Вот базовое решение:
ave(df,df$iso, FUN =function(y){
if(nrow(y) > 1) y[3:5] <- lapply(y[3:5], function(x) approx(y$year,x,y$year,rule=2)$y)
y
})
# iso year var1 var2 var3
# 1 XXX 2005 165 29 2151.0
# 2 XXX 2006 160 21 2139.0
# 3 XXX 2007 172 15 2889.5
# 4 XXX 2008 184 9 3640.0
# 5 XXX 2009 184 9 3640.0
# 6 YYY 2005 206 461 8049.0
Мы можем использовать mutate_at
. Ключ должен указать правильные столбцы в аргументе vars
, который использует то же правило, что и функция select
. Поэтому в этом случае vars(starts_with("var"))
также будет работать.
library(dplyr)
library(zoo)
df1 %>%
group_by(iso) %>%
mutate_at(vars(-iso, -year), funs(na.approx(., na.rm = FALSE, rule = 1))) %>%
mutate_at(vars(-iso, -year), funs(na.locf(., na.rm = FALSE))) %>%
mutate_at(vars(-iso, -year), funs(na.locf(., na.rm = FALSE, fromLast = TRUE)))
# # A tibble: 6 x 5
# # Groups: iso [2]
# iso year var1 var2 var3
# <chr> <int> <dbl> <dbl> <dbl>
# 1 XXX 2005 165 29 2151
# 2 XXX 2006 160 21 2139
# 3 XXX 2007 172 15 2890.
# 4 XXX 2008 184 9 3640
# 5 XXX 2009 184 9 3640
# 6 YYY 2005 206 461 8049
DATA
df1 <- read.table(text = " iso year var1 var2 var3
1 XXX 2005 165 29 2151
2 XXX 2006 160 21 2139
3 XXX 2007 NA NA NA
4 XXX 2008 184 9 3640
5 XXX 2009 NA NA NA
6 YYY 2005 206 461 8049 ",
header = TRUE, stringsAsFactors = FALSE)
mutate_at
:-) – MKR 13 July 2018 в 21:27var1
,var2
и т. Д., Поэтому я не могу ссылаться на них, как вы предлагали. Использование ссылки @www var и вложенность функций заставили ее работать. Благодаря! – Alexander91 13 July 2018 в 21:55