2015-07-30 3 views
1

У меня есть кадр данных, глядя, как это:Объединить колонки в одном кадре данных

df = 
A B C D E  F 
1 NA NA 10.2 8.9 abc 
2 NA NA 65.1 7.6 def 
3 76.1 10.1 NA NA ghi 
4 10.1 10.4 NA NA jkl 
5 NA NA NA NA mno 

В конце концов, мне нужно, чтобы выглядеть следующим образом:

df = 
A B C F 
1 10.2 8.9 abc 
2 65.1 7.6 def 
3 76.1 10.1 ghi 
4 10.1 10.4 jkl 
5 NA NA mno 

Все NA в C и D необходимо заменить значениями от D и E, если они имеют значение! Все остальные столбцы должны быть сохранены!

+0

@akrun спасибо, что указал, что опечатка! – Stophface

+0

Другая опция, использующая 'max.col'' indx <- max.col (! Is.na (df [2: 5]), 'first'); df [2: 3] <- df [2: 5] [ cbind (1: nrow (df), c (indx, indx + 1))]; df [c (1: 3,6)] ' – akrun

ответ

2

ifelse прекрасно работает в этих ситуациях.

library(dplyr) 
mutate(df, B = ifelse(is.na(B), D, B), 
      C = ifelse(is.na(C), E, C)) 
+0

К сожалению. Этот последний 'D' должен быть' C'. но в остальном я думаю, что это правильно. Я запускаю его снова. – Benjamin

+0

Редактирование, описанное выше, возвращает правильное значение. Спасибо, что поймал это. – Benjamin

+0

аккуратный. Мне нравится это. Благодаря! – Stophface

1

Использование базы R, то это должно быть как быстро и масштабируемые (для многих колонок):

foo <- function(x, y) pmax(x, y, na.rm=TRUE) 
cols1 = c("B", "C") 
cols2 = c("D", "E") 

df[, cols1] = with(df, Map(foo, mget(cols1), mget(cols2))) 
df = df[, !(names(df) %in% cols2), drop = FALSE] 

или же концепция с использованием data.table v1.9.5 - инструкции по установке here

require(data.table) # v1.9.5+ 
setDT(df)[, (cols1) := Map(foo, mget(cols1), mget(cols2))][, (cols2) := NULL] 

Идея довольно проста. Используя pmax с na.rm=TRUE на каждую пару столбцов, по одному за раз, используя Map().

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