说我有这个数据框:
# Original data frame
df_1 <- data.frame(a = sample(1:10, 5),
b = letters[1:5],
c = sample(c(TRUE, FALSE), 5, replace = TRUE),
d = 6:10)
# a b c d
#1 7 a FALSE 6
#2 9 b TRUE 7
#3 3 c TRUE 8
#4 5 d TRUE 9
#5 6 e TRUE 10
我还有第二个数据框,其中有一些与第一个相同的列:
# Data frame with wonky data types
df_2 <- data.frame(a = as.character(sample(1:10, 5)),
foo = 1:5,
b = letters[1:5],
bar = runif(5),
c = as.character(sample(c(TRUE, FALSE), 5, replace = TRUE)),
stringsAsFactors = FALSE)
# a foo b bar c
#1 10 1 a 0.1185343 FALSE
#2 5 2 b 0.3081978 TRUE
#3 6 3 c 0.4409280 TRUE
#4 8 4 d 0.5081508 FALSE
#5 7 5 e 0.7404537 FALSE
请注意df_2
与df_1
共有的列(即a
,b
,c
)不一定具有相同的数据键入df_1
中的相应列。例如,a
中的df_1
属于integer
类型,而a
中的df_2
属于character
类型。
我想要做的是将df_2
中同样存在于df_1
中的所有列转换为df_1
列的数据类型。
我的第一个希望是我可以绑定它们并且会自动进行转换:
library(dplyr)
bind_rows(df_1, df_2)
但是,没有:
bind_rows_(x,.id)出错:列
a
无法从 整数到字符
所以,我的下一次尝试是弄清楚哪些列是共同的:
# Common columns
common <- names(df_2)[names(df_2) %in% names(df_1)]
现在,如果我想将它们全部转换为numeric
,我可以使用
df_2 %>% mutate_at(common, as.numeric)
但它们都是不同的数据类型,所以我需要使用相应的数据类型。我认为不管怎样我可以使用as
传递来自lapply(df_1, class)
的相应类,但细节让我不知所措。我认为必须有一个简单,优雅的解决方案,而且我已经过时了,但到目前为止我还没有运气。有什么想法吗?
答案 0 :(得分:2)
使用match.fun
的某些内容可行:
str(df_1) ## The source classes...
# 'data.frame': 5 obs. of 4 variables:
# $ a: int 4 2 5 9 8
# $ b: Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5
# $ c: logi FALSE FALSE TRUE FALSE FALSE
# $ d: int 6 7 8 9 10
str(df_2) ## Before conversion
# 'data.frame': 5 obs. of 5 variables:
# $ a : chr "8" "10" "9" "3" ...
# $ foo: int 1 2 3 4 5
# $ b : chr "a" "b" "c" "d" ...
# $ bar: num 0.294 0.34 0.372 0.459 0.736
# $ c : chr "FALSE" "TRUE" "TRUE" "FALSE" ...
这是转换步骤:
df_2[common] <- lapply(common, function(x) {
match.fun(paste0("as.", class(df_1[[x]])))(df_2[[x]])
})
str(df_2) ## After conversion
# 'data.frame': 5 obs. of 5 variables:
# $ a : int 8 10 9 3 1
# $ foo: int 1 2 3 4 5
# $ b : Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5
# $ bar: num 0.294 0.34 0.372 0.459 0.736
# $ c : logi FALSE TRUE TRUE FALSE FALSE