通过行/列名称在第三维上联接数据框

时间:2018-09-12 12:25:10

标签: r

我有任意数量的数据帧,带有行和列的名称。

我的目标是在第三维上使用行/列名称作为连接键来连接那些数据框,即,我希望结果是一个命名的三维数组。

我的问题是我不想按位置加入他们,而希望通过他们的行/列名来加入他们。

我知道我可以使用 abind()沿任意所需的维级联数组,但可以按位置绑定数据,而不是按暗名进行连接。

在sql中,我希望使用行/列名称作为联接键进行完全联接,但要沿第三维进行。

这里有一个只有两个数据帧的可重现的小示例:

first <- data.frame(one=c(1,2), two=c(3,4), row.names = c("one", "two"))
second <- data.frame(one=c(10,20), three=c(50,60), row.names = c("one", "three"))
result <- someMagicFunction(first, second)

我对“结果”对象的期望输出是:

result <- array(data=c(1, 2, NA, 3, 4, NA, NA, NA, NA,
                       10, NA, 20, NA, NA, NA, 50, NA, 60), 
                dim = c(3, 3, 2), 
                dimnames = list(
                  c("one", "two", "three"),
                  c("one", "two", "three"),
                  c("first", "second")))
> result
, , first

      one two three
one     1   3    NA
two     2   4    NA
three  NA  NA    NA

, , second

      one two three
one    10  NA    50
two    NA  NA    NA
three  20  NA    60

我自己编写了一个函数来完成任务,但是我想知道是否已经有内置函数来完成该任务。

谢谢!

2 个答案:

答案 0 :(得分:1)

library(abind)
library(magrittr)

in.dfs <- list(first, second)

cols <- unique(unlist(lapply(in.dfs, names)))
rows <- unique(unlist(lapply(in.dfs, rownames)))

allNA <- 
  matrix(NA, length(cols), length(rows)) %>% 
    `colnames<-`(cols) %>% 
    `rownames<-`(rows)

lapply(in.dfs, function(df){
  allNA[rownames(df), names(df)] <- as.matrix(df)
  allNA
}) %>% 
  list(along = 3) %>% 
  do.call(what = abind)

结果

# , , 1
# 
#       one two three
# one     1   3    NA
# two     2   4    NA
# three  NA  NA    NA
# 
# , , 2
# 
#       one two three
# one    10  NA    50
# two    NA  NA    NA
# three  20  NA    60

答案 1 :(得分:0)

对“数组”一词不清楚。我会这样解决:

如果您正在寻找快速 base 优雅解决方案:

数据:

//Parent.js
class Parent extends Component {
    component(props) {
        super(props)

        this.state = {
            test: 'abc'
        }
    }

    ParentFunction = (value) => {
        this.state.test = value;
        this.setState(this.state);
    }

    render() {

        return (
            <div>
                <Child
                    test={this.state.test}
                    ParentFunction={this.ParentFunction}
                />
            </div>
        );
    }
}


//Child.js

import s from './Child.css';

class Child extends Component {
    component(props) {
        super(props)

        this.state = {
            test: props.test
        }
    }

    handleChange = () => {
        this.state.test = event.target.value;
        this.setState(this.state);
        this.handleOnSave()
    }

    handleOnSave = () => {
        this.props.ParentFunction(this.state.test);
    }

    render() {
        return (
            <div> 
                <input type="text" onChange={this.handleChange} />
            </div>
        );
    }
}

export default withStyles(s)(Child);

代码:

first <- data.frame(one=c(1,2), two=c(3,4), row.names = c("one", "two"))
second <- data.frame(one=c(10,20), three=c(50,60), row.names = c("one", "three"))

l <- list(first, second)

结果:

dn <- unique(c(sapply(l, names)))

model<-as.data.frame(structure(rep(NA,length(dn)^2), .Dim = c(length(dn), length(dn)), .Dimnames = list(dn, dn)))

lapply(l, function(el){model[names(el),names(el)] <- el;model})