Заменить пропущенные значения - PullRequest
0 голосов
/ 06 сентября 2018
M     Price Quantity    Quantity1
---------------------------------
2014m1  55  150          150
2014m2  55  220          220
2014m3  55  350          87,5
2014m4  55  NA           87,5
2014m5  55  NA           87,5
2014m6  55  NA           87,5
2014m8  58  200           200

Это образец моего стола. А именно, я хочу получить результат вроде Количество1. Это означает, что если какое-либо значение равно NA, код должен делиться на числа NA плюс 1.

E.g 350 следует заменить на 87,5 (= 350/4), а также следующие три значения следует заменить на 87,5.

Так кто-нибудь может мне помочь с этим кодом с циклом?

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

С Base R мы можем использовать ave:

df$Quantity1 = ave(df$Quantity, cumsum(!is.na(df$Quantity)), 
                   FUN = function(x) max(x, na.rm = TRUE)/length(x))

Также с data.table (кредиты @Jaap):

library(data.table)

setDT(df)[, Quantity1 := max(Quantity, na.rm = TRUE)/.N, by = cumsum(!is.na(Quantity))]

Выход:

       M Price Quantity Quantity1
1 2014m1    55      150     150.0
2 2014m2    55      220     220.0
3 2014m3    55      350      87.5
4 2014m4    55       NA      87.5
5 2014m5    55       NA      87.5
6 2014m6    55       NA      87.5
7 2014m8    58      200     200.0

или dplyr:

library(dplyr)

df %>%
  group_by(na_id = cumsum(!is.na(Quantity))) %>%
  mutate(Quantity1 = max(Quantity, na.rm = TRUE)/n()) 

Примечание: мы можем добавить ungroup() %>% select(-na_id) для удаления столбца na_id.

Выход:

# A tibble: 7 x 5
# Groups:   na_id [4]
  M      Price Quantity na_id Quantity1
  <fct>  <int>    <int> <int>     <dbl>
1 2014m1    55      150     1     150  
2 2014m2    55      220     2     220  
3 2014m3    55      350     3      87.5
4 2014m4    55       NA     3      87.5
5 2014m5    55       NA     3      87.5
6 2014m6    55       NA     3      87.5
7 2014m8    58      200     4     200  

Данные:

df <- structure(list(M = structure(1:7, .Label = c("2014m1", "2014m2", 
"2014m3", "2014m4", "2014m5", "2014m6", "2014m8"), class = "factor"), 
    Price = c(55L, 55L, 55L, 55L, 55L, 55L, 58L), Quantity = c(150L, 
    220L, 350L, NA, NA, NA, 200L)), class = "data.frame", row.names = c(NA, 
-7L), .Names = c("M", "Price", "Quantity"))
0 голосов
/ 06 сентября 2018

Я думаю, приведенный ниже код работает для вас:

getValueindices<-function(dt){which( is.na(dt))-1  } #find replace candidate


setValue<-function(indices,dt ){            # replace Na with previous value
  for(i in indices)
    if(min(indices)==i)
      dt[i+1]<-dt[i]/(sum(is.na(dt))+1)
    else
      dt[i+1]<-dt[i]
  dt
} 

getValueindices(df$Quantity)
setValue(indices,df$Quantity)

df$Quantity1<- setValue(indices,df$Quantity)

df

и вывод:

       M Price Quantity Quantity1
1 2014m1    55      150     150.0
2 2014m2    55      220     220.0
3 2014m3    55      350     350.0
4 2014m4    55       NA      87.5
5 2014m5    55       NA      87.5
6 2014m6    55       NA      87.5
7 2014m8    58      200     200.0
...