2016-11-26 15 views
-2

Я хотел бы попросить сообщество R объединить две строки с тем же идентификатором (то есть тем же участником) с некоторыми одинаковыми переменными и другими, где есть NA. В моем примере я хотел бы, чтобы все значения 4-5-6 отображались в одной строке и, следовательно, для NA (или пустых ячеек).Слияние двух строк с некоторыми отсутствующими значениями в R

This is an example of what my data looks like

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

+1

Пожалуйста, не используйте изображения. Предоставьте примерные входные данные как R-код, который можно скопировать и вставить в R, чтобы воспроизвести вход. Я сделал это для вас на этот раз в Заметке в конце моего ответа. См. [Mcve] для получения дополнительной информации. –

+0

Возможный дубликат [Объединение строк с общей информацией] (http://stackoverflow.com/questions/39920870/merging-rows-with-shared-information) – jdobres

+0

@ G.Grothendieck Хорошо, спасибо за информацию. – Elmo556

ответ

2

1) Используя DF, указанные в примечании ниже, попробуйте агрегировать с использованием функции compress, определенной ниже. Эта функция удаляет значения NA и добавляет NA на всякий случай, когда все значения были удалены, а затем берет первый из оставшихся. Пакеты не используются.

compress <- function(x) c(na.omit(x), NA)[1] 
aggregate(DF[5:7], DF[1:4], compress) 

дает:

ID Value1 Value2 Value3 Value4 Value5 Value6 
1 1  A  B  C  x  x  x 
2 2  A  B  C  x  x  x 

2) Более простой альтернативой, если ни один из участников не имеет все значения NA в любом столбце, что мы могли бы исключить определение из compress и использовать max с na.rm = TRUE вместо как это :

aggregate(DF[5:7], DF[1:4], max, na.rm = TRUE) 

Примечание: Вход в воспроизводимой форме:

Lines <- "ID Value1 Value2 Value3 Value4 Value5 Value6 
1 A B C x x NA 
1 A B C NA NA x 
2 A B C NA x NA 
2 A B C x NA x" 
DF <- read.table(text = Lines, header = TRUE, as.is = TRUE) 
2
# Create sample data frame. 
id <- c(rep('Participant 1', 2), rep('Participant 2', 2)) 
value1 <- rep('A', 4) 
value2 <- rep('B', 4) 
value3 <- rep('C', 4) 
value4 <- c('x', NA, NA, 'x') 
value5 <- c('x', NA, 'x', NA) 
value6 <- c(NA, 'x', NA, 'x') 

df <- data.frame(id, value1, value2, value3, value4, value5, value6, stringsAsFactors = F) 

# Use dplyr to group the data and keep the non-NA value from the other columns. 
df %>% group_by(id, value1, value2, value3) %>% 
     summarise(value4 = max(value4, na.rm = T), 
       value5 = max(value5, na.rm = T), 
       value6 = max(value6, na.rm = T)) 
0

Если вы предпочитаете использовать dplyr попробовать:

library(dplyr) 
DF %>% 
    group_by(ID, Value1, Value2, Value3) %>% 
    summarise_each(funs(toString(na.omit(.)))) 

Результат:

 ID Value1 Value2 Value3 Value4 Value5 Value6 
    <int> <chr> <chr> <chr> <chr> <chr> <chr> 
1  1  A  B  C  x  x  x 
2  2  A  B  C  x  x  x 

Примечание:

1

Другое решение docendo discimus с dplyr и tidyr:

library(dplyr) 
library(tidyr) 
DF %>% 
    gather(var, val, Value4:Value6) %>% 
    filter(!is.na(val)) %>% 
    spread(var, val) 

с использованием данных @G. Grothendieck, это приводит к:

ID Value1 Value2 Value3 Value4 Value5 Value6 
1 1  A  B  C  x  x  x 
2 2  A  B  C  x  x  x 

Или другой вариант с summarise_each с подходом max @G.Гротендик:

DF %>% 
    group_by(ID, Value1, Value2, Value3) %>% 
    summarise_each(funs(max(., na.rm = TRUE))) 

В gather и spread опции также могут быть переведены в раствор с reshape2:

library(reshape2) 
dcast(na.omit(melt(DF, id.vars = c('ID','Value1','Value2','Value3'))), 
     ID + Value1 + Value2 + Value3 ~ variable, 
     value.var = 'value') 

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

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