Объедините неравные фреймы данных и замените отсутствующие строки на 0
у меня есть два данных.фреймы, один с только символами, а другой с символами и значениями.
df1 = data.frame(x=c('a', 'b', 'c', 'd', 'e'))
df2 = data.frame(x=c('a', 'b', 'c'),y = c(0,1,0))
merge(df1, df2)
x y
1 a 0
2 b 1
3 c 0
Я хочу объединить df1 и df2. Символы a, b и c слились хорошо, а также имеют 0, 1, 0, но d и e ничего не имеют. Я хочу, чтобы d и e также были в таблице слияния с условием 0 0. Таким образом, для каждой отсутствующей строки в данных df2.кадр, 0 должен быть помещен в таблицу df1, например:
x y
1 a 0
2 b 1
3 c 0
4 d 0
5 e 0
4 ответа:
взгляните на страницу справки для слияния. Элемент
all
параметр позволяет указать различные типы слияний. Здесь мы хотим установитьall = TRUE
. Это сделает merge returnNA
для значений, которые не совпадают, которые мы можем обновить до 0 сis.na()
:zz <- merge(df1, df2, all = TRUE) zz[is.na(zz)] <- 0 > zz x y 1 a 0 2 b 1 3 c 0 4 d 0 5 e 0
или, как альтернатива коду @Chase, будучи недавним поклонником plyr с фоном в базах данных:
require(plyr) zz<-join(df1, df2, type="left") zz[is.na(zz)] <- 0
еще одна альтернатива с данными.стол.
ПРИМЕР
dt1 <- data.table(df1) dt2 <- data.table(df2) setkey(dt1,x) setkey(dt2,x)
код
dt2[dt1,list(y=ifelse(is.na(y),0,y))]
Я ответ дал Чейз (ответил 11 мая '11 в 14:21), но я добавил немного кода, чтобы применить это решение моей конкретной проблемы.
У меня был фрейм ставок (пользователь, загрузка) и фрейм итогов (пользователь, загрузка), которые будут объединены пользователем, и я хотел включить каждую ставку, даже если не было соответствующего итога. Однако отсутствующих итогов не может быть, и в этом случае выбор строк для замены NA на ноль не будет выполнен.
первый строка кода выполняет слияние. Следующие две строки изменяют имена столбцов в объединенном фрейме. Оператор if заменяет NA на ноль, но только если есть строки с NA.
# merge rates and totals, replacing absent totals by zero graphdata <- merge(rates, totals, by=c("user"),all.x=T) colnames(graphdata)[colnames(graphdata)=="download.x"] = "download.rate" colnames(graphdata)[colnames(graphdata)=="download.y"] = "download.total" if(any(is.na(graphdata$download.total))) { graphdata[is.na(graphdata$download.total),]$download.total <- 0 }