2016-04-06 2 views
0

было интересно, если это было бы возможно объединить различные строки на dataframe, если они имеют 1 поле общее:Объединить строки из той же dataframe

вход:

df = rbind(c("01/01/2016",01:02:30,"100","character(0)","file A"), 
      c("02/01/2016",9:02:30,"character(0)", 3, "file A"), 
      c("02/01/2016",8:30:30,"200","character(0)","file B"), 
      c("03/01/2016",8:25:30,"50","character(0)","file C"), 
      c("04/01/2016",17:20:30,"character(0)","600","file B")) 

выход:

df = rbind(c(01/01/2016,01:02:30,"100",3,"file A"), 
      c(02/01/2016,8:30:30,"200",600,"file B"), 
      c(03/01/2016,8:25:30,"50","character(0)","file C")) 

Так как вы можете видеть, что мы объединяем строки в соответствии с последним значением (файл A, файл B или файл C). Мне нужно сохранить самые ранние даты. например, для «файла А» у нас есть 2 даты 01/01/2016 и 02/01/2016, мы хотим сохранить , мы не будем объединять более двух строк за значение

Мы хотим сохранить самую раннюю дату

+1

Вы можете использовать 'dplyr :: group_by' или' data.table' 'by =' и получить значения 'min()'. BTW, ваши примеры ввода и вывода бросают предупреждения. –

ответ

2

На основании ваших комментариев вы хотите найти первый экземпляр (упорядоченный по одному столбцу) не пропущенного значения для каждого столбца на основе столбца группировки (в вашем случае столбец «файл A/B/C») ,

Сначала вам придется немного очистить данные. Шаг загрузки данных ошибочен из-за некоторых неуместных кавычек вокруг временных меток. Кроме того, я предполагаю, что вы хотите представить отсутствующие значения с помощью значений character(0). Если да, используйте NA s. Вот инициализация данных и этап очистки:

# prepare your data 
df = data.frame(V1 = c("01/01/2016 01:02:30","02/01/2016 9:02:30","02/01/2016 8:30:30", 
         "03/01/2016 8:25:30","04/01/2016 17:20:30"), 
       V2 = c("100","character(0)","200","50","character(0)"), 
       V3 = c("character(0)", "3", "character(0)","character(0)", "600"), 
       V4 = c("file A", "file A", "file B", "file C", "file B")) 

# replace the character(0)s with NAs as they are missing values 
df[df == "character(0)"] <- NA 

# convert character dates to time 
df$V1 <- strptime(as.character(df[ ,1]), format = "%d/%m/%Y %H:%M:%S") 

я назвал столбцы V1..4, но вы, вероятно, хотите, чтобы некоторые более описательные имена. Чтобы получить то, что вам нужно, вы должны заполнить недостающие значения для столбцов, используя функцию zoo пакета na.locf(). Чтобы устранить перекрестное загрязнение данных по разным значениям столбца V4, я просматриваю данные. (Там может быть лучшим решением для этого ...) Вот функция, чтобы сделать ваш пользовательский ряд слияния:

custom_row_merge <- function(df, 
          sort_by, 
          group_by){ 

    # sort by dates in decreasing order 
    df <- df[order(df[,group_by], df[,sort_by]), ] 

    # select the columns to merge 
    columns_to_merge <- names(df)[!(names(df) %in% c(sort_by, group_by))] 

    # fill data for each unique value of group by column 
    for (file_type in unique(df[, group_by])){ 

     row_indices <- (df[,group_by] == file_type) 

     # fill missing values for each column that is not group by or sort by 
     for (column_name in columns_to_merge){ 

      df[row_indices, column_name] <- na.locf(df[row_indices, column_name], 
                na.rm = F, 
                fromLast = T) 
     }  

    } 

    # get first occurence of each file, now with the filled values 
    return(df[!duplicated(df[, group_by]), ]) 

} 

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

> df 
        V1 V2 V3  V4 
1 2016-01-01 01:02:30 100 <NA> file A 
2 2016-01-02 09:02:30 <NA> 3 file A 
3 2016-01-02 08:30:30 200 <NA> file B 
4 2016-01-03 08:25:30 50 <NA> file C 
5 2016-01-04 17:20:30 <NA> 600 file B 

И один произведенный функцией, соответствие, что вы описали в своем вопросе:

> custom_row_merge(df, "V1", "V4") 
        V1 V2 V3  V4 
1 2016-01-01 01:02:30 100 3 file A 
3 2016-01-02 08:30:30 200 600 file B 
4 2016-01-03 08:25:30 50 <NA> file C 

конечно, вы можете заполнить недостающие значения с characer(0) значениями, если вы хотите.

+0

Я получаю это: Ошибка в df [, 1] <- strptime (df [, 1], format = "% d /% m /% Y% H:% M:% S"): Количество элементов для замены не кратно длины замены –

+0

@ManuelSopenaBallesteros Вы пробовали мое назначение df? В вашем вопросе есть опечатка, где часть времени H: M: S является отдельной и не комментируется. Дайте мне знать, если это решит вашу проблему. – niczky12

+0

Да, я пробовал использовать ваш набор данных, не работал. спасибо –

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