Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当两个数据帧具有不同的列集时,按行组合两个数据帧(rbind)_R_Dataframe_R Faq - Fatal编程技术网

当两个数据帧具有不同的列集时,按行组合两个数据帧(rbind)

当两个数据帧具有不同的列集时,按行组合两个数据帧(rbind),r,dataframe,r-faq,R,Dataframe,R Faq,是否可以对不具有相同列集的两个数据帧进行行绑定?我希望在绑定后保留不匹配的列 您可以使用gtools软件包中的smartbind 例如: library(gtools) df1 <- data.frame(a = c(1:5), b = c(6:10)) df2 <- data.frame(a = c(11:15), b = c(16:20), c = LETTERS[1:5]) smartbind(df1, df2) # result a b c 1.1 1

是否可以对不具有相同列集的两个数据帧进行行绑定?我希望在绑定后保留不匹配的列

您可以使用
gtools
软件包中的
smartbind

例如:

library(gtools)
df1 <- data.frame(a = c(1:5), b = c(6:10))
df2 <- data.frame(a = c(11:15), b = c(16:20), c = LETTERS[1:5])
smartbind(df1, df2)
# result
     a  b    c
1.1  1  6 <NA>
1.2  2  7 <NA>
1.3  3  8 <NA>
1.4  4  9 <NA>
1.5  5 10 <NA>
2.1 11 16    A
2.2 12 17    B
2.3 13 18    C
2.4 14 19    D
2.5 15 20    E
库(gtools)

df1您也可以只提取公共列名

> cols <- intersect(colnames(df1), colnames(df2))
> rbind(df1[,cols], df2[,cols])
cols rbind(df1[,cols],df2[,cols])
rbind。从包中填充
plyr
可能就是您要查找的内容。

如果df1中的列是df2中的列的子集(按列名):


df3也许我完全误解了你的问题,但是“我希望保留绑定后不匹配的列”让我觉得你在寻找类似SQL查询的
左连接
右连接。R具有
merge
函数,可用于指定左、右或内部联接,类似于SQL中的联接表


关于这个主题,这里已经有一个很好的问题和答案:

我写了一个函数来做这件事,因为我喜欢我的代码来告诉我是否有什么问题。此函数将显式告诉您哪些列名不匹配以及是否存在类型不匹配。然后它将尽最大努力组合data.frames。限制是一次只能合并两个data.Frame

### combines data frames (like rbind) but by matching column names
# columns without matches in the other data frame are still combined
# but with NA in the rows corresponding to the data frame without
# the variable
# A warning is issued if there is a type mismatch between columns of
# the same name and an attempt is made to combine the columns
combineByName <- function(A,B) {
    a.names <- names(A)
    b.names <- names(B)
    all.names <- union(a.names,b.names)
    print(paste("Number of columns:",length(all.names)))
    a.type <- NULL
    for (i in 1:ncol(A)) {
        a.type[i] <- typeof(A[,i])
    }
    b.type <- NULL
    for (i in 1:ncol(B)) {
        b.type[i] <- typeof(B[,i])
    }
    a_b.names <- names(A)[!names(A)%in%names(B)]
    b_a.names <- names(B)[!names(B)%in%names(A)]
    if (length(a_b.names)>0 | length(b_a.names)>0){
        print("Columns in data frame A but not in data frame B:")
        print(a_b.names)
        print("Columns in data frame B but not in data frame A:")
        print(b_a.names)
    } else if(a.names==b.names & a.type==b.type){
        C <- rbind(A,B)
        return(C)
    }
    C <- list()
    for(i in 1:length(all.names)) {
        l.a <- all.names[i]%in%a.names
        pos.a <- match(all.names[i],a.names)
        typ.a <- a.type[pos.a]
        l.b <- all.names[i]%in%b.names
        pos.b <- match(all.names[i],b.names)
        typ.b <- b.type[pos.b]
        if(l.a & l.b) {
            if(typ.a==typ.b) {
                vec <- c(A[,pos.a],B[,pos.b])
            } else {
                warning(c("Type mismatch in variable named: ",all.names[i],"\n"))
                vec <- try(c(A[,pos.a],B[,pos.b]))
            }
        } else if (l.a) {
            vec <- c(A[,pos.a],rep(NA,nrow(B)))
        } else {
            vec <- c(rep(NA,nrow(A)),B[,pos.b])
        }
        C[[i]] <- vec
    }
    names(C) <- all.names
    C <- as.data.frame(C)
    return(C)
}
###通过匹配列名来组合数据帧(如rbind)
#其他数据框中不匹配的列仍将合并
#但在与数据帧对应的行中使用NA,而不使用
#变量
#如果列之间存在类型不匹配,将发出警告
#使用相同的名称并尝试合并列

combineByNamegtools/smartbind不喜欢处理日期,可能是因为它是as.vectoring。这是我的解决方案

sbind = function(x, y, fill=NA) {
    sbind.fill = function(d, cols){ 
        for(c in cols)
            d[[c]] = fill
        d
    }

    x = sbind.fill(x, setdiff(names(y),names(x)))
    y = sbind.fill(y, setdiff(names(x),names(y)))

    rbind(x, y)
}

最近的解决方案是使用
dplyr
bind\u rows
函数,我认为该函数比
smartbind
更有效

df1 <- data.frame(a = c(1:5), b = c(6:10))
df2 <- data.frame(a = c(11:15), b = c(16:20), c = LETTERS[1:5])
dplyr::bind_rows(df1, df2)
    a  b    c
1   1  6 <NA>
2   2  7 <NA>
3   3  8 <NA>
4   4  9 <NA>
5   5 10 <NA>
6  11 16    A
7  12 17    B
8  13 18    C
9  14 19    D
10 15 20    E
rbind(
  data.frame(c(df1, sapply(setdiff(names(df2), names(df1)), function(x) NA))),
  data.frame(c(df2, sapply(setdiff(names(df1), names(df2)), function(x) NA)))
)

df1数据的替代方案。表

library(data.table)
df1 = data.frame(a = c(1:5), b = c(6:10))
df2 = data.frame(a = c(11:15), b = c(16:20), c = LETTERS[1:5])
rbindlist(list(df1, df2), fill = TRUE)

rbind
也将在
data.table
中工作,只要对象转换为
data.table
对象,那么

rbind(setDT(df1), setDT(df2), fill=TRUE)

在这种情况下也会起作用。如果您有两个data.tables,并且不想构建列表,则最好使用此选项。

仅用于文档。您可以按以下形式尝试
Stack
库及其函数
Stack

Stack(df_1, df_2)

我的印象是,对于大型数据集,它比其他方法更快。

大多数基本R答案都解决了只有一个data.frame具有附加列或者生成的data.frame将具有列的交点的情况。因为OP写了我希望保留绑定后不匹配的列,所以使用base R方法解决这个问题的答案可能值得发布

下面,我将介绍两种基本的R方法:一种改变原始data.frames,另一种不改变。此外,我还提供了一种方法,将非破坏性方法推广到两个以上的data.frames

首先,让我们获取一些示例数据

# sample data, variable c is in df1, variable d is in df2
df1 = data.frame(a=1:5, b=6:10, d=month.name[1:5])
df2 = data.frame(a=6:10, b=16:20, c = letters[8:12])

两个data.frames,更改原始文件
为了在
rbind
中保留两个data.frames中的所有列(并允许该函数在不产生错误的情况下工作),您可以使用
setdiff
将NA列添加到每个data.frames中,并填入适当的缺失名称

# fill in non-overlapping columns with NAs
df1[setdiff(names(df2), names(df1))] <- NA
df2[setdiff(names(df1), names(df2))] <- NA
请注意,前两行更改了原始data.frames、df1和df2,并向这两行添加了完整的列集


两个data.frames,请勿更改原件
要保持原始data.frames不变,首先循环不同的名称,返回NAs的命名向量,使用
c
将其与data.frames连接到一个列表中。然后,
data.frame
将结果转换为
rbind
的适当data.frame

df1 <- data.frame(a = c(1:5), b = c(6:10))
df2 <- data.frame(a = c(11:15), b = c(16:20), c = LETTERS[1:5])
dplyr::bind_rows(df1, df2)
    a  b    c
1   1  6 <NA>
2   2  7 <NA>
3   3  8 <NA>
4   4  9 <NA>
5   5 10 <NA>
6  11 16    A
7  12 17    B
8  13 18    C
9  14 19    D
10 15 20    E
rbind(
  data.frame(c(df1, sapply(setdiff(names(df2), names(df1)), function(x) NA))),
  data.frame(c(df2, sapply(setdiff(names(df1), names(df2)), function(x) NA)))
)

许多data.frames,不改变原件
在具有两个以上data.frames的实例中,可以执行以下操作

# put data.frames into list (dfs named df1, df2, df3, etc)
mydflist <- mget(ls(pattern="df\\d+"))
# get all variable names
allNms <- unique(unlist(lapply(mydflist, names)))

# put em all together
do.call(rbind,
        lapply(mydflist,
               function(x) data.frame(c(x, sapply(setdiff(allNms, names(x)),
                                                  function(y) NA)))))
您还可以使用,它使用
dplyr::bind_rows()
,但与
bind_rows()
不同,
add_rows()
保留属性,因此对于

请参见以下带有标签数据集的示例。
frq()
-函数用于打印带有值标签的频率表(如果数据有标签)

library(sjmisc)
library(dplyr)

data(efc)
# select two subsets, with some identical and else different columns
x1 <- efc %>% select(1:5) %>% slice(1:10)
x2 <- efc %>% select(3:7) %>% slice(11:20)

str(x1)
#> 'data.frame':    10 obs. of  5 variables:
#>  $ c12hour : num  16 148 70 168 168 16 161 110 28 40
#>   ..- attr(*, "label")= chr "average number of hours of care per week"
#>  $ e15relat: num  2 2 1 1 2 2 1 4 2 2
#>   ..- attr(*, "label")= chr "relationship to elder"
#>   ..- attr(*, "labels")= Named num  1 2 3 4 5 6 7 8
#>   .. ..- attr(*, "names")= chr  "spouse/partner" "child" "sibling" "daughter or son -in-law" ...
#>  $ e16sex  : num  2 2 2 2 2 2 1 2 2 2
#>   ..- attr(*, "label")= chr "elder's gender"
#>   ..- attr(*, "labels")= Named num  1 2
#>   .. ..- attr(*, "names")= chr  "male" "female"
#>  $ e17age  : num  83 88 82 67 84 85 74 87 79 83
#>   ..- attr(*, "label")= chr "elder' age"
#>  $ e42dep  : num  3 3 3 4 4 4 4 4 4 4
#>   ..- attr(*, "label")= chr "elder's dependency"
#>   ..- attr(*, "labels")= Named num  1 2 3 4
#>   .. ..- attr(*, "names")= chr  "independent" "slightly dependent" "moderately dependent" "severely dependent"

bind_rows(x1, x1) %>% frq(e42dep)
#> 
#> # e42dep <numeric> 
#> # total N=20  valid N=20  mean=3.70  sd=0.47
#>  
#>   val frq raw.prc valid.prc cum.prc
#>     3   6      30        30      30
#>     4  14      70        70     100
#>  <NA>   0       0        NA      NA

add_rows(x1, x1) %>% frq(e42dep)
#> 
#> # elder's dependency (e42dep) <numeric> 
#> # total N=20  valid N=20  mean=3.70  sd=0.47
#>  
#>  val                label frq raw.prc valid.prc cum.prc
#>    1          independent   0       0         0       0
#>    2   slightly dependent   0       0         0       0
#>    3 moderately dependent   6      30        30      30
#>    4   severely dependent  14      70        70     100
#>   NA                   NA   0       0        NA      NA
库(sjmisc)
图书馆(dplyr)
数据(efc)
#选择两个子集,其中有些列相同,有些列不同
x1%选择(1:5)%>%切片(1:10)
x2%选择(3:7)%>%切片(11:20)
str(x1)
#>“data.frame”:10个obs。共有5个变量:
#>$C12小时:数字16148 70 168 161 110 28 40
#>..-attr(*,“标签”)=chr“每周平均护理小时数”
#>$e15relat:数量2 1 2 2
#>..-属性(*,“标签”)=chr“与长者的关系”
#>..-attr(*,“标签”)=命名编号1 2 3 4 5 6 7 8
#>   .. ..- attr(*,“姓名”)=chr“配偶/伴侣”“子女”“兄弟姐妹”“女儿或女婿”。。。
#>$E16性别:数字2
#>..-属性(*,“标签”)=chr“长者性别”
#>..-attr(*,“标签”)=命名编号1 2
#>   .. ..- 属性(*,“名称”)=chr“男性”或“女性”
#>$E17年龄:数字83 88 82 67 84 85 74 87 79 83
#>..-属性(*,“标签”)=chr“长者年龄”
#>$e42dep:num 3 3 4 4 4
#>..-attr(*,“label”)=chr“长者依赖”
#>..-attr(*,“标签”)=命名编号1 2 3 4
#>   .. ..- attr(*,“name”)=chr“独立”“轻度依赖”“中度依赖”“严重依赖”
绑定行(x1,x1)%>%frq(e42dep)
#> 
#>#e42dep
#>#总N=20有效N=20平均值=3.70 sd=0.47
#>  
#>val frq原始中国有效中国与中国
#>     3   6      30        30      30
#>     4  14      70        70     100
#>0毫微纳
添加行(x1,x1)%>%frq(e42dep)
#> 
#> #
do.call(rbind,
        c(lapply(mydflist,
                 function(x) data.frame(c(x, sapply(setdiff(allNms, names(x)),
                                                    function(y) NA)))),
          make.row.names=FALSE))
library(sjmisc)
library(dplyr)

data(efc)
# select two subsets, with some identical and else different columns
x1 <- efc %>% select(1:5) %>% slice(1:10)
x2 <- efc %>% select(3:7) %>% slice(11:20)

str(x1)
#> 'data.frame':    10 obs. of  5 variables:
#>  $ c12hour : num  16 148 70 168 168 16 161 110 28 40
#>   ..- attr(*, "label")= chr "average number of hours of care per week"
#>  $ e15relat: num  2 2 1 1 2 2 1 4 2 2
#>   ..- attr(*, "label")= chr "relationship to elder"
#>   ..- attr(*, "labels")= Named num  1 2 3 4 5 6 7 8
#>   .. ..- attr(*, "names")= chr  "spouse/partner" "child" "sibling" "daughter or son -in-law" ...
#>  $ e16sex  : num  2 2 2 2 2 2 1 2 2 2
#>   ..- attr(*, "label")= chr "elder's gender"
#>   ..- attr(*, "labels")= Named num  1 2
#>   .. ..- attr(*, "names")= chr  "male" "female"
#>  $ e17age  : num  83 88 82 67 84 85 74 87 79 83
#>   ..- attr(*, "label")= chr "elder' age"
#>  $ e42dep  : num  3 3 3 4 4 4 4 4 4 4
#>   ..- attr(*, "label")= chr "elder's dependency"
#>   ..- attr(*, "labels")= Named num  1 2 3 4
#>   .. ..- attr(*, "names")= chr  "independent" "slightly dependent" "moderately dependent" "severely dependent"

bind_rows(x1, x1) %>% frq(e42dep)
#> 
#> # e42dep <numeric> 
#> # total N=20  valid N=20  mean=3.70  sd=0.47
#>  
#>   val frq raw.prc valid.prc cum.prc
#>     3   6      30        30      30
#>     4  14      70        70     100
#>  <NA>   0       0        NA      NA

add_rows(x1, x1) %>% frq(e42dep)
#> 
#> # elder's dependency (e42dep) <numeric> 
#> # total N=20  valid N=20  mean=3.70  sd=0.47
#>  
#>  val                label frq raw.prc valid.prc cum.prc
#>    1          independent   0       0         0       0
#>    2   slightly dependent   0       0         0       0
#>    3 moderately dependent   6      30        30      30
#>    4   severely dependent  14      70        70     100
#>   NA                   NA   0       0        NA      NA