使用 id 匹配和替换因子值
Matching and replacing factor values using id
我有两个数据框,每个数据框都包含相同的变量和每个观察的唯一 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.2
以在合并的 data.frame
中同时保留 v1
和 v2
。 运行 逻辑用值 v2
替换缺失的 v1
。
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>
现在可以删除 v2
列
使用data.table
和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
1: 334 4 dogs
2: 440 4 dogs
3: 501 3 dogs
4: 2304 5 dogs
5: 2500 No dogs
到此为止 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)
第二种解决方案:
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)
PS:我更喜欢将字符串作为字符向量
正如@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)
输出
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
把上面的结果存入一个变量(df),然后检查str(df)
'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
如果您想删除 v1
和 v2
列,只需将最终结果通过管道传输到 %>% select(id,final)
希望它有效。
我有两个数据框,每个数据框都包含相同的变量和每个观察的唯一 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.2
以在合并的 data.frame
中同时保留 v1
和 v2
。 运行 逻辑用值 v2
替换缺失的 v1
。
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>
现在可以删除 v2
列
使用data.table
和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
1: 334 4 dogs
2: 440 4 dogs
3: 501 3 dogs
4: 2304 5 dogs
5: 2500 No dogs
到此为止 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)
第二种解决方案:
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)
PS:我更喜欢将字符串作为字符向量
正如@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)
输出
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
把上面的结果存入一个变量(df),然后检查str(df)
'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
如果您想删除 v1
和 v2
列,只需将最终结果通过管道传输到 %>% select(id,final)
希望它有效。