R:从面板结构到邻接矩阵或边列表?

时间:2018-12-28 14:04:33

标签: r

我正在尝试将长格式面板结构中的数据集转换为邻接矩阵或边列表以制作网络图。数据集包含每个商品,每个商品都由ID号标识。每篇文章可以在多个类别下出现多次。因此,目前我的格式结构很长:

    <Toolbar
        android:id="@+id/mytoolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </Toolbar>

    <ScrollView
        android:layout_above="@+id/adView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >


        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >


            <RelativeLayout
                android:gravity="center_vertical"
                android:background="#ffffffff"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content">
                <LinearLayout android:orientation="vertical"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="15.0dip">

                    <TextView
                        android:textSize="17.0sp"
                        android:textColor="#ff000000"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Extreme power saving mode" />

                </LinearLayout>

                <Switch
                    android:id="@+id/setSwitch1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginRight="10.0dip"
                    android:layout_alignParentRight="true"
                    android:layout_centerVertical="true" />
            </RelativeLayout>
            </LinearLayout>
</ScrollView>


<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal"
    android:gravity="bottom">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <com.google.android.gms.ads.AdView
            android:id="@+id/adView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            ads:adSize="SMART_BANNER"
            ads:adUnitId="@string/ad_banner">

        </com.google.android.gms.ads.AdView>
    </LinearLayout>
</LinearLayout>

我想将其转换为邻接矩阵或边列表。边缘列表看起来像这样

ID <- c(1,1,1,2,2,2,3,3)
Category <- c("A","B","C","B","E","H","C","E")
dat <- data.frame(ID,Category)

编辑:我已经尝试过A B A C B C B E B H E H C E ,但是它返回了错误消息dat <- merge(ID, Category, by="Category")

预先感谢

更新:我最终在评论中使用了Error in fix.by(by.x, x) : 'by' must specify a uniquely valid column,但是下面的海军郑先生建议的解决方案也能有效

2 个答案:

答案 0 :(得分:1)

此代码将起作用

do.call(rbind,lapply(split(dat, dat$ID), function(x){
   t(combn(as.vector(x$Category), 2))
}))

更新

根据@Parfait的建议,您可以使用 by 代替 split + lapply

1)使用 by Category 类别将节点(“ A”,“ B”,“ C” ...)分组;

2)使用 combn 在每个组中的节点之间创建边,并使用 t 变换矩阵以进一步进行 rbind

> edge.list <- by(dat, dat$ID, function(x) t(combn(as.vector(x$Category), 2)))

dat$ID: 1
     [,1] [,2]
[1,] "A"  "B" 
[2,] "A"  "C" 
[3,] "B"  "C" 
------------------------------------------------------------ 
dat$ID: 2
     [,1] [,2]
[1,] "B"  "E" 
[2,] "B"  "H" 
[3,] "E"  "H" 
------------------------------------------------------------ 
dat$ID: 3
     [,1] [,2]
[1,] "C"  "E" 

3)然后合并列表

> do.call(rbind, edge.list)

    [,1] [,2]
[1,] "A"  "B" 
[2,] "A"  "C" 
[3,] "B"  "C" 
[4,] "B"  "E" 
[5,] "B"  "H" 
[6,] "E"  "H" 
[7,] "C"  "E"

答案 1 :(得分:0)

因此,如果您愿意将data.frame转换为data.table,则可以非常有效且干净地解决此问题,并且如果您有很多行,则速度会更快。

    library(data.table)
    dat<-data.table(dat)

基本上,您可以将函数应用于j单元格中data.table的列,以及k单元格中的组。因此,您希望每个ID一次采用两个类别的所有组合,如下所示:

    dat[,combn(Categories,2),by=ID]

但是,此时停止将保留ID列,并且默认情况下会创建一个称为V1的列,该列基本上将由combn返回的数组连接到类别的向量中,而不是所需的两列邻接矩阵。但是通过链接对此的另一个调用,您可以像使用任何单个矢量一样轻松地创建矩阵。在一行代码中,它将类似于:

    dat[,combn(Category,2),by=ID][,matrix(V1,ncol=2,byrow = T)]

请记住,我们希望转换为矩阵的向量列默认情况下称为V1,并且我们希望按行创建2列矩阵,而不是按列创建默认值。希望能对您有所帮助,并让我知道是否需要在说明中添加任何内容。祝你好运!