2017-01-03 11 views
0

Я работаю с временными рядами данных о осадках и пытаюсь использовать метод медианного вменения для замены всех точек данных значения с медианой из всех точек данных за соответствующий месяц было записано значение 0.Заменить значения в соответствии с месяцами в кадре данных со значениями в другом столбце в r, используя функции приложения

У меня есть два кадра данных, один с исходными данными осадков:

> head(df.m) 
     prcp  date 
1 121.00485 1975-01-31 
2 122.41667 1975-02-28 
3 82.74026 1975-03-31 
4 104.63514 1975-04-30 
5 57.46667 1975-05-31 
6 38.97297 1975-06-30 

И один с среднемесячными значениями:

> medians 
    Group.1   x 
1  01 135.90680 
2  02 123.52613 
3  03 113.09841 
4  04 98.10044 
5  05 75.21976 
6  06 57.47287 
7  07 54.16667 
8  08 45.57653 
9  09 77.87740 
10  10 103.25179 
11  11 124.36795 
12  12 131.30695 

Ниже текущим решение, которое я придумал с использованием 1-го ответа here:

df.m[,"prcp"] <- sapply(df.m[,"prcp"], function(y) ifelse(y==0, medians$x,y)) 

Это имеет не работает, поскольку применяется только первое значение df medians$Group.1, которое является январем (01). Как я могу получить значения, чтобы правильная медиана применялась с соответствующего месяца?

Другой способ, который я попытался решение это через ниже:

df.m[,"prcp"] <- sapply(medians$Group.1, function(y) 
       ifelse(df.m[format.Date(df.m$date, "%m") == y & 
       df.m$prcp == 0, "prcp"], medians[medians$Group.1 == y,"x"], 
       df.m[,"prcp"])) 

Описание выше функции - функция тестов и возвращает количество нулей за каждый месяц, что есть нулевое значение в df.m[,"prcp"] Такая же проблема здесь как 1-е решение, но она возвращает все значения 0 по месяцам (если просто выполняется часть sapply()).

Как я могу заменить все 0 на df.m$prcp с их соответствующими медианами от medians df в зависимости от месяца данных?

Извините, если это основной вопрос, я немного новичок здесь. Любая помощь будет очень признательна.

+0

Являются ли dataframes одинаковой длины? Какие годы соответствует среднему месячному значению? – Parfait

+0

Данные не одинаковой длины. 'df.m' - 504 строки, а' medians' - 12 строк (показано выше). Медианные месяцы не имеют лет, они являются медианами этого конкретного месяца для всего набора данных. Эти значения я хотел бы добавить в свой 'df.m', где' df.m $ prcp' == 0, в зависимости от месяца. – steich

ответ

1

Рассмотрим объединение двух dataframes по месяцам/группе, а затем вычисления с ifelse:

# MERGE TWO FRAMES 
df.m$month <- format(df.m$date, "%m") 
df.merge <- merge(df.m, medians, by.x="month", by.y="Group.1") 

# CONDITIONAL CALCULATION 
df.merge$prcp <- ifelse(df.merge$prcp == 0, df.merge$x, df.merge$prcp) 

# RETURN BACK TO ORIGINAL STRUCTURE 
df.m <- df.merge[names(df.m)] 
+0

Это решение было очень полезно и работает с любым фильтром (вместо изменения значений 0, например, для всех значений <15. Можете ли вы объяснить, почему объединение двух кадров данных будет повторять медианные значения? Мое основное понимание заключалось в том, чтобы объединить два кадра данных по столбцам, они должны были иметь одинаковую длину. – steich

+0

О нет, 'merge()' подобен SQL 'JOIN' и связывает записи, сопоставляя значения определенных переменных (то есть имена' by'). для нескольких совпадений за значение. Вы думаете о 'cbind()', который требует равной длины, но не соответствует критериям соответствия. – Parfait

0

Я создал небольшие наборы данных с некоторыми нулевыми значениями и добавил одну строку кода:

#create sample data  
prcp <- c(1.5,0.0,0.0,2.1) 
date <- c(01,02,03,04) 
x <- c(1.11,2.22,3.33,4.44) 

df <- data.frame(prcp,date) 
grp <- data.frame(x,date) 

#Make the assignment 
df[df$prcp == 0,]$prcp <- grp[df$prcp == 0,]$x 
+0

Это предполагает, что даты относятся к порядку индекса со срединной группой и одинаковым размером. Нам нужно ОП, чтобы подтвердить это. – Parfait

1

A версия dplyr, которая не основывается на первоначальном порядке. Это использует несколько модифицирована тестовые данные, чтобы показать замену нулей и несколько лет

require(dplyr) 

## test data with zeroes - extended for addtional years 
df.m <- read.delim(text=" 
i prcp date 
1 121.00485 1975-01-31 
2 122.41667 1975-02-28 
3 82.74026 1975-03-31 
4 104.63514 1975-04-30 
5 57.46667 1975-05-31 
6 38.97297 1975-06-30 
7 0 1976-06-30 
8 0 1976-07-31 
9 70 1976-08-31 
", sep="", stringsAsFactors = FALSE) 

medians <- read.delim(text=" 
i month x 
1  01 135.90680 
2  02 123.52613 
3  03 113.09841 
4  04 98.10044 
5  05 75.21976 
6  06 57.47287 
7  07 54.16667 
8  08 45.57653 
9  09 77.87740 
10  10 103.25179 
11  11 124.36795 
12  12 131.30695 
", sep = "", stringsAsFactors = FALSE, strip.white = TRUE) 

# extract the month as integer 
df.m$month = as.integer(substr(df.m$date,6,7)) 

# match to medians by joining 
result <- df.m %>% 
    inner_join(medians, by='month') %>% 
    mutate(prcp = ifelse(prcp == 0, x, prcp)) %>% 
    select(prcp, date) 

result 

Урожайность

 prcp  date 
1 121.00485 1975-01-31 
2 122.41667 1975-02-28 
3 82.74026 1975-03-31 
4 104.63514 1975-04-30 
5 57.46667 1975-05-31 
6 38.97297 1975-06-30 
7 57.47287 1976-06-30 
8 54.16667 1976-07-31 
9 70.00000 1976-08-31 
+0

Почему dplyr? Базовые 'merge()' и 'ifelse()' могли бы это сделать. – Parfait

+0

Просто личное предпочтение для более последовательного набора функций манипуляции данными. – epi99

 Смежные вопросы

  • Нет связанных вопросов^_^