R 使用id匹配和替换因子值

R 使用id匹配和替换因子值,r,data-manipulation,recode,R,Data Manipulation,Recode,我有两个数据帧,两个数据帧都包含相同的变量,每个观测值都有一个唯一的id df.1是一个大型数据集,其中包含由NA表示的缺失值。这些缺失条目的值包含在df.2中,我希望通过匹配id,将df.1中的缺失替换为df.2中的值 我还没有找到一个类似的问题,考虑到他们都是因素变量 更简单:如果id匹配,df.1中缺少的值应替换为df.2中的因子值。 df.1 <- data.frame(id = c(334,440,501,2304,2500), v1 = c("

我有两个数据帧,两个数据帧都包含相同的变量,每个观测值都有一个唯一的id

df.1是一个大型数据集,其中包含由NA表示的缺失值。这些缺失条目的值包含在df.2中,我希望通过匹配id,将df.1中的缺失替换为df.2中的值

我还没有找到一个类似的问题,考虑到他们都是因素变量

更简单:如果id匹配,df.1中缺少的值应替换为df.2中的因子值。

df.1 <- data.frame(id = c(334,440,501,2304,2500), 
                v1 = c("4 dogs",NA,"3 dogs",NA,"No dogs"))

df.2 <- data.frame(id = c(440,2304), 
                v2 = c("4 dogs","5 dogs"))

df.1您可以加入
df.1
df.2
v1
v2
保留在合并的
数据框中。运行逻辑以将缺少的
v1
替换为
v2

library(dplyr)

df.1 <- data.frame(id = c(334,440,501,2304,2500), 
                   v1 = c("4 dogs",NA,"3 dogs",NA,"No dogs"))

df.2 <- data.frame(id = c(440,2304), 
                   v2 = c("4 dogs","5 dogs"))
#merge using left_join to keep all rows from df.1
final <- df.1 %>%
  left_join(df.2, by = "id")
#> final
#    id      v1     v2
#1  334  4 dogs   <NA>
#2  440    <NA> 4 dogs
#3  501  3 dogs   <NA>
#4 2304    <NA> 5 dogs
#5 2500 No dogs   <NA>

#Define a function to replace missing v1
replMissing <- function(x, y){
  ifelse(is.na(x), y, x )
}

#call replMissing function using mapply. Modified to handle factor
final$v1 <- as.factor(mapply(replMissing, as.character(final$v1), as.character(final$v2)))

#results is
#> final
#    id      v1     v2
#1  334  4 dogs   <NA>
#2  440  4 dogs 4 dogs
#3  501  3 dogs   <NA>
#4 2304  5 dogs 5 dogs
#5 2500 No dogs   <NA>
库(dplyr)

df.1使用
数据表和
dplyr
:-

library(data.table)
library(dplyr)
df <- left_join(df.1, df.2, by = "id")
setDT(df)
df[is.na(v1), v1 := v2]
df[, v2 := NULL]
至此,
id
将是数字,
v1
将是系数。如果希望
id
也转换为因子。您可以使用以下方法进行操作:-

df[, id := as.factor(id)]

使用
tidyverse
方法,您有两种解决方案:

第一个解决方案:

library(dplyr)
df.1 <- data.frame(id = c(334,440,501,2304,2500), 
                   v1 = c("4 dogs",NA,"3 dogs",NA,"No dogs"),stringsAsFactors=F) 

df.2 <- data.frame(id = c(440,2304), 
                   v2 = c("4 dogs","5 dogs"),stringsAsFactors=F) %>% 
    rename(v1=v2)

df_mix <- bind_rows(df.1,df.2) %>% 
    drop_na(...=v1)
库(dplyr)

df.1正如@Gregor提到的,您可以将df转换回因子。这里方便的函数是@MrFlick的
coalesce
函数。解决办法不言自明

library(dplyr)

df.1 %>%
  left_join(df.2, by = "id") %>%
  mutate_if(is.factor, as.character) %>%
  mutate(final = coalesce(v1, v2))  %>% mutate_if(is.character, as.factor)
输出

如果要删除
v1
v2
列,只需将最终结果输送到
%%>%选择(id,final)


希望它能起作用

你检查过这些了吗,我想这已经被回答了。不幸的是,情况并非如此。我希望代码简单地匹配两个变量之间的ID,并将df.2中的值替换为df.1。ID仅指定df.1中缺少的值。为什么需要将它们保留为两个因子变量?只需在(merge(df.1,df.2,all=TRUE),{V1=pmax(as.character(V1),as.character(v2),na.rm=TRUE);rm(V1,v2)}内转换为
字符
…很容易在最后转换回因子。是否有可能的解决方案将它们更改回因子并保留其原来的所有级别?@dayleymart修改了解决方案以处理
因子
值。实际上,在调用
mapply
时需要进行转换。使用此方法变量是否会丢失其因子类型?因此,
v1
将是因子<代码>id
将是数字。如果您想再次使用
id
因子。您可以使用
df[,id:=as.factor(id)]
。若你们愿意的话,我会在答案中加上它。抱歉,ID始终是数字的,并且可以保持数字,因为它只是一个唯一的标识符。谢谢。很酷,反正我加了。如果您需要,您可以使用它。刚刚使用了您的代码并查看了新创建的v1变量的摘要。似乎“NA”已被添加为df1中所有未替换的缺失值的一个因子…您有没有解决方案将它们转换回缺失值?
df.1 <- data.frame(id = c(334,440,501,2304,2500), 
                   v1 = c("4 dogs",NA,"3 dogs",NA,"No dogs"),stringsAsFactors=F)

df.2 <- data.frame(id = c(440,2304), 
                   v2 = c("4 dogs","5 dogs"),stringsAsFactors=F) 

df_mix <- left_join(df.1,df.2,by="id") %>% 
    mutate(v1=case_when(
        is.na(v1) ~ v2,
        !is.na(v1) ~ v1
    )) %>% 
    select(1:2)
library(dplyr)

df.1 %>%
  left_join(df.2, by = "id") %>%
  mutate_if(is.factor, as.character) %>%
  mutate(final = coalesce(v1, v2))  %>% mutate_if(is.character, as.factor)
   id      v1     v2   final
1  334  4 dogs   <NA>  4 dogs
2  440    <NA> 4 dogs  4 dogs
3  501  3 dogs   <NA>  3 dogs
4 2304    <NA> 5 dogs  5 dogs
5 2500 No dogs   <NA> No dogs
'data.frame':   5 obs. of  4 variables:
 $ id   : num  334 440 501 2304 2500
 $ v1   : Factor w/ 3 levels "3 dogs","4 dogs",..: 2 NA 1 NA 3
 $ v2   : Factor w/ 2 levels "4 dogs","5 dogs": NA 1 NA 2 NA
 $ final: Factor w/ 4 levels "3 dogs","4 dogs",..: 2 2 1 3 4