Program Club

동일하지 않은 데이터 프레임을 병합하고 누락 된 행을 0으로 바꿉니다.

proclub 2020. 12. 4. 21:08
반응형

동일하지 않은 데이터 프레임을 병합하고 누락 된 행을 0으로 바꿉니다.


두 개의 data.frame이 있는데, 하나는 문자 만 있고 다른 하나는 문자와 값이 있습니다.

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에는 아무것도 없습니다. 0 0 조건으로 병합 테이블에서도 d와 e를 원합니다. 따라서 df2 data.frame에서 누락 된 모든 행에 대해 다음과 같이 df1 테이블에 0을 배치해야합니다.

  x y
1 a 0
2 b 1
3 c 0
4 d 0
5 e 0

병합에 대한 도움말 페이지를 살펴보십시오. all매개 변수는 병합의 다른 유형을 지정할 수 있습니다. 여기서 우리는 all = TRUE. 이렇게하면 NA일치하지 않는 값에 대해 병합이 반환 되며 다음을 사용하여 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

몇 년 후 후속 질문을 해결하기 위해 업데이트 됨

병합하지 않는 두 번째 데이터 테이블에서 변수 이름을 식별해야합니다 setdiff(). 저는 이것을 위해 사용 합니다. 다음을 확인하십시오.

df1 = data.frame(x=c('a', 'b', 'c', 'd', 'e', NA))
df2 = data.frame(x=c('a', 'b', 'c'),y1 = c(0,1,0), y2 = c(0,1,0))

#merge as before
df3 <- merge(df1, df2, all = TRUE)
#columns in df2 not in df1
unique_df2_names <- setdiff(names(df2), names(df1))
df3[unique_df2_names][is.na(df3[, unique_df2_names])] <- 0 

2019-01-03에 reprex 패키지 (v0.2.1)로 생성됨


또는 @Chase의 코드에 대한 대안으로 데이터베이스에 대한 배경 지식이있는 최근의 plyr 팬이되었습니다.

require(plyr)
zz<-join(df1, df2, type="left")
zz[is.na(zz)] <- 0

data.table의 또 다른 대안.

예제 데이터

dt1 <- data.table(df1)
dt2 <- data.table(df2)
setkey(dt1,x)
setkey(dt2,x)

암호

dt2[dt1,list(y=ifelse(is.na(y),0,y))]

나는 Chase가 제공 한 대답을 사용했지만 (2011 년 5 월 11 일 14:21에 대답), 그 해결책을 내 특정 문제에 적용하기 위해 약간의 코드를 추가했습니다.

사용자별로 병합 할 속도 프레임 (사용자, 다운로드)과 총 프레임 (사용자, 다운로드)이 있었으며 해당하는 합계가 없더라도 모든 속도를 포함하고 싶었습니다. 그러나 누락 된 합계가 없을 수 있으며이 경우 NA를 0으로 대체 할 행 선택이 실패합니다.

The first line of code does the merge. The next two lines change the column names in the merged frame. The if statement replaces NA by zero, but only if there are rows with 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
}

Assuming df1 has all the values of x of interest, you could use a dplyr::left_join() to merge and then either a base::replace() or tidyr::replace_na() to replace the NAs as 0s:

library(tidyverse)

# dplyr only:
df_new <- 
  left_join(df1, df2, by = 'x') %>% 
  mutate(y = replace(y, is.na(y), 0))

# dplyr and tidyr:
df_new <- 
  left_join(df1, df2, by = 'x') %>% 
  mutate(y = replace_na(y, 0))

# In the sample data column `x` is a factor, which will give a warning with the join. This can be prevented by converting to a character before the join:
df_new <- 
  left_join(df1 %>% mutate(x = as.character(x)), 
            df2 %>% mutate(x = as.character(x)), 
            by = 'x') %>% 
    mutate(y = replace(y, is.na(y), 0))

참고URL : https://stackoverflow.com/questions/5965698/merge-unequal-dataframes-and-replace-missing-rows-with-0

반응형