dplyr bind_rows突变类型以匹配

时间:2018-07-10 02:32:47

标签: r dplyr

说我有两个简单的数据框,如下所示:

stuff <- data.frame('a', 'b')
col1 <- c(1,2,3)
stuff <- data.frame(col1)
col1 <- c('1','2', '3')
stuff2 <- data.frame(col1)

我想将它们合并为一个数据帧,并尝试使用dplyr的{​​{1}},例如像这样:

bind_rows

但是(毫不奇怪)我得到了

  

bind_rows_(x,.id)中的错误:     bind_rows(stuff, stuff2) 列无法从数字转换为因数

我是否可以告诉col1将行突变为目标(或尝试)?

3 个答案:

答案 0 :(得分:1)

您可以尝试同时使用rbind(...)这两个data.frame具有相同名称的相同列数。

rbind(stuff, stuff2, stringsAsFactors = FALSE)

#   col1
# 1    1
# 2    2
# 3    3
# 4    1
# 5    2
# 6    3

选项#2:如果列名不同

一个人可以尝试使用c(...)的自动强制能力。该功能的文档建议如下:

All arguments are coerced to a common type which is the type of the returned value,
and all attributes except names are removed

现在,如果所有data.frames的列数和顺序相同,那么您可以尝试以下操作:

library(purrr)

map2_df(stuff, stuff2, c)

# # A tibble: 6 x 1
#    col1
#   <dbl>
# 1  1.00
# 2  2.00
# 3  3.00
# 4  1.00
# 5  2.00
# 6  3.00

注意:请确保在应用上述代码之前,将所有factor类型的列都转换为character类型,以避免出现意外结果。

数据:

col1 <- c(1,2,3)
stuff <- data.frame(col1)
col1 <- c('1','2', '3')
stuff2 <- data.frame(col1)

答案 1 :(得分:1)

我会使用data.table的rbindlist ... 由于此功能需要一个列表作为输入,因此您将自动丢失字符因子问题...

rbindlist还具有一些使生活更轻松的功能(而且速度也非常快!)

#lets make'a named list
l <- list( stuff = stuff, stuff2 = stuff2 ) 
#now bind the two df's together
library(data.table)
rbindlist( l, use.names = TRUE )
#    col1
# 1:    1
# 2:    2
# 3:    3
# 4:    1
# 5:    2
# 6:    3

当您需要更多功能时,会出现更好的东西。假设您想知道哪个数据来自哪个df ...在这里,名称列表起作用了

rbindlist( l, use.names = TRUE, idcol = TRUE )
#      .id col1
#1:  stuff    1
#2:  stuff    2
#3:  stuff    3
#4: stuff2    1
#5: stuff2    2
#6: stuff2    3

或者,当并非所有df中都存在所有同名字符时:

col2 <- c('1','2', '3')
stuff2 <- data.frame(col2)
rbindlist( l, use.names = TRUE, fill = TRUE, idcol = "origin" )
#    origin col1 col2
# 1:  stuff    1 <NA>
# 2:  stuff    2 <NA>
# 3:  stuff    3 <NA>
# 4: stuff2   NA    1
# 5: stuff2   NA    2
# 6: stuff2   NA    3

如果列名不相同,但是您仍然想将两个df放在一列中:

col1 <- c(1,2,3)
stuff <- data.frame(col1)
col2 <- c('1','2', '3')
stuff2 <- data.frame(col2)
#create a named list
l <- list(stuff = stuff, stuff2 = stuff2) 
rbindlist( l )

#    col1
# 1:    1
# 2:    2
# 3:    3
# 4:    1
# 5:    2
# 6:    3

答案 2 :(得分:0)

如果您有多种数据类型,请尝试以下操作:

#data
stuff <- data.frame('a', 'b')
col1 <- c(1,2,3)
stuff <- data.frame(col1)
col1 <- c('1','2', '3')
stuff2 <- data.frame(col1)
#for loop to convert classes from one df to the other
for (x in colnames(stuff)) {
  stuff[,x] <- eval(call( paste0("as.", class(stuff2[,x])), stuff[,x]) )}
#bind_rows
bind_rows(stuff,stuff2)