Использование R для объединения данных в кварталы - PullRequest
0 голосов
/ 14 марта 2020

Я пишу очень просто, если еще l oop, чтобы создать новую переменную, которая преобразует другую переменную в квартили. Кажется, это очень простая процедура, однако l oop группирует все мои данные в медиану и третий квартиль (что нарушает определение квартиля).

Вот структура моих данных:

> str(tmp)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   435 obs. of  12 variables:
 $ CD112FP             : chr  "01" "02" "03" "04" ...
 $ State               : chr  "ALABAMA" "ALABAMA" "ALABAMA" "ALABAMA" ...
 $ Year                : num  2011 2011 2011 2011 2011 ...
 $ Alignment           : num  0 0 0 0 0 0 1 0 0 0 ...
 $ State_Aligned       : num  0 0 0 0 0 0 0 1 0 0 ...
 $ PercentFunding      : num  0.0658 0.29 0.6764 0.0174 0.047 ...
 $ fips                : chr  "01" "01" "01" "01" ...
 $ ssa                 : int  1 1 1 1 1 1 1 NA 3 3 ...
 $ region              : int  3 3 3 3 3 3 3 NA 4 4 ...
 $ division            : int  6 6 6 6 6 6 6 NA 8 8 ...
 $ abb                 : chr  "AL" "AL" "AL" "AL" ...
 $ PercentFundingBinned: chr  "0.0625-0.1799" "0.0625-0.1799" "0.0625-0.1799" "0.0625-0.1799" ...

, и это заголовок моих данных:

 head(tmp)
# A tibble: 6 x 12
  CD112FP State    Year Alignment State_Aligned PercentFunding fips    ssa region division abb   PercentFundingBinned
  <chr>   <chr>   <dbl>     <dbl>         <dbl>          <dbl> <chr> <int>  <int>    <int> <chr> <chr>               
1 01      ALABAMA  2011         0             0         0.0658 01        1      3        6 AL    0.0625-0.1799       
2 02      ALABAMA  2011         0             0         0.290  01        1      3        6 AL    0.0625-0.1799       
3 03      ALABAMA  2011         0             0         0.676  01        1      3        6 AL    0.0625-0.1799       
4 04      ALABAMA  2011         0             0         0.0174 01        1      3        6 AL    0.0625-0.1799       
5 05      ALABAMA  2011         0             0         0.0470 01        1      3        6 AL    0.0625-0.1799       
6 06      ALABAMA  2011         0             0         0.0440 01        1      3        6 AL    0.0625-0.1799       

Я использую следующее, если еще l oop:

  tmp$PercentFundingBinned <- NULL
  if (tmp$PercentFunding >= quantile(tmp$PercentFunding, 0.75)) {
    tmp$PercentFundingBinned <- paste0(round(quantile(tmp$PercentFunding, 0.75), 4), "-",
                                       round(max(tmp$PercentFundingBinned), 4))
  } else if (tmp$PercentFunding >= median(tmp$PercentFunding)){
    tmp$PercentFundingBinned <- paste0(round(median(tmp$PercentFunding),4), "-", 
                                       round(quantile(tmp$PercentFunding, 0.75),4))
  } else if (tmp$PercentFunding >= quantile(tmp$PercentFunding, 0.25)){
    tmp$PercentFundingBinned <- paste0(round(quantile(tmp$PercentFunding, 0.25),4), "-", 
                                       round(median(tmp$PercentFunding),4))
  } else {
    tmp$PercentFundingBinned <- paste0(round(min(tmp$PercentFunding),4), "-", 
                                             round(quantile(tmp$PercentFunding, 0.25),4))
  }

и он возвращает следующую категорию:

unique(tmp$PercentFundingBinned)
[1] "0.0625-0.1799"

Не уверен, что делать или как соответствовать. Кажется, это должно быть очень простой процедурой. Любой совет помогает, спасибо!

Ответы [ 2 ]

2 голосов
/ 14 марта 2020

Я полагаю, вам вообще не нужно ifelse.

tmp <- read.table(header=TRUE, stringsAsFactors=FALSE, text="
  CD112FP State    Year Alignment State_Aligned PercentFunding fips    ssa region division abb   PercentFundingBinned
1 01      ALABAMA  2011         0             0         0.0658 01        1      3        6 AL    0.0625-0.1799       
2 02      ALABAMA  2011         0             0         0.290  01        1      3        6 AL    0.0625-0.1799       
3 03      ALABAMA  2011         0             0         0.676  01        1      3        6 AL    0.0625-0.1799       
4 04      ALABAMA  2011         0             0         0.0174 01        1      3        6 AL    0.0625-0.1799       
5 05      ALABAMA  2011         0             0         0.0470 01        1      3        6 AL    0.0625-0.1799       
6 06      ALABAMA  2011         0             0         0.0440 01        1      3        6 AL    0.0625-0.1799       ")
quants <- quantile(tmp$PercentFunding, c(0, 0.25, 0.5, 0.75, 1))
quants
#      0%     25%     50%     75%    100% 
# 0.01740 0.04475 0.05640 0.23395 0.67600 
cuts <- cut(tmp$PercentFunding,
            quants, include.lowest = TRUE, dig.lab = 4,
            labels = sprintf("%0.04f-%0.04f", head(quants, n = -1), quants[-1]))
cuts
# [1] 0.0564-0.2339 0.2339-0.6760 0.2339-0.6760 0.0174-0.0447 0.0447-0.0564 0.0174-0.0447
# Levels: 0.0174-0.0447 0.0447-0.0564 0.0564-0.2339 0.2339-0.6760

Конечно, это factor, но при необходимости его можно легко конвертировать с as.character.

tmp$PercentFundingBinned <- as.character(cuts)
0 голосов
/ 14 марта 2020

Я настоятельно рекомендую вам всегда обращать внимание на предупреждения .

Вы не должны использовать if при работе с векторами, потому что, как показано в предупреждении, только первое будет использоваться элемент:

> if(c(TRUE, FALSE)) 1 else 2
[1] 1
Warning message:
In if (c(TRUE, FALSE)) 1 else 2 :
  the condition has length > 1 and only the first element will be used
> if(c(FALSE, TRUE)) 1 else 2
[1] 2
Warning message:
In if (c(FALSE, TRUE)) 1 else 2 :
  the condition has length > 1 and only the first element will be used

В вашем случае происходит следующее: первое значение равно 0.0658, поэтому if определяет, что оно находится в корзине 0.0625-0.1799. И поскольку вы присваиваете одно значение для вектора, это значение присваивается каждому элементу вектора.

Вместо этого вы можете использовать ifelse:

tmp$PercentFundingBinned <- ifelse (
  tmp$PercentFunding >= quantile(tmp$PercentFunding, 0.75) , 
  paste0(round(quantile(tmp$PercentFunding, 0.75), 4), "-",
         round(max(tmp$PercentFundingBinned), 4)),
  ifelse(tmp$PercentFunding >= median(tmp$PercentFunding),
         paste0(round(median(tmp$PercentFunding),4), "-",
                round(quantile(tmp$PercentFunding, 0.75),4)),
         ifelse(tmp$PercentFunding >= quantile(tmp$PercentFunding, 0.25),
                paste0(round(quantile(tmp$PercentFunding, 0.25),4), "-", 
                       round(median(tmp$PercentFunding),4)), 
                paste0(round(min(tmp$PercentFunding),4), "-", 
                       round(quantile(tmp$PercentFunding, 0.25),4))
         )
    )
)
...