根据ID将频率表与现有数据帧合并

时间:2012-12-23 09:39:32

标签: r dataframe

我拥有的是什么:

从我原来的观察......

video_id  user_id keyword
1         1       foo
2         1       bar
3         1       baz
4         1       yak
1         2       foo
2         2       bar
3         2       blah
4         2       yak
1         3       foo
2         3       bar
3         3       blah
4         3       yak

...我有一张频率表(称为tab),它以我想要的确切格式显示,例如。

video_id  foo bar baz yak blah
1         4   0   0   0   0
2         0   4   0   0   0
3         0   0   2   0   2
4         0   0   0   4   0

我想根据ID列将此表与现有数据框(称为data)合并。因此,例如,它还包含另外两列:

video_id  col1  col2
1         123   412
2         652   633
3         749   144
4         1738  1763

我需要什么:

我需要根据视频ID合并频率表和现有数据帧。请注意,它不一定是排序的,所以我不能只cbind它们。这是我需要的结果:

video_id  col1  col2  foo bar baz yak blah
1         123   412   4   0   0   0   0
2         652   633   0   4   0   0   0
3         749   144   0   0   2   0   2
4         1738  1763  0   0   0   4   0

现在,我知道我可以得到这样的数据框矩阵:

as.data.frame.matrix(table(…))

但是这个矩阵缺少video_id列,当我只查看表时实际显示了该列。那么,我该如何获取仍包含video_id列或行名称的数据框呢?

我需要video_id列在数据框中首先出现,然后是原始列,然后然后附加表格数据,如上例所示。

我尝试了什么:

  • 我知道我可以通过rownames(table(…))获取表格的行名称,我可以得到我想要的结果

    cbind(data.frame(video_id=rownames(tab)), as.data.frame.matrix(tab))
    

    但这对我来说似乎并不干净(足够)。

  • 直接与

    合并
    merge(data, as.data.frame.matrix(tab))
    

    为我提供了所有结果,但video_id列位于表格数据和原始数据之间,因此顺序不正确。

2 个答案:

答案 0 :(得分:1)

我做了什么:

data <- read.table(text = "video_id  col1  col2
1         123   412
2         652   633
3         749   144
4         1738  1763", header = TRUE)

tab <- read.table(text = "video_id  user_id keyword
1         1       foo
2         1       bar
3         1       baz
4         1       yak
1         2       foo
2         2       bar
3         2       blah
4         2       yak
1         3       foo
2         3       bar
3         3       blah
4         3       yak", header = TRUE)

tt <- aggregate(keyword ~ video_id, data = tab, FUN = table)
mrg <- merge(data, tt)
mrg

  video_id col1 col2 keyword.bar keyword.baz keyword.blah keyword.foo keyword.yak
1        1  123  412           0           0            0           3           0
2        2  652  633           3           0            0           0           0
3        3  749  144           0           1            2           0           0
4        4 1738 1763           0           0            0           0           3

现在我们有了“奇怪的”列名。如果你不能忍受,那就是“黑客”。

tmp <- data.frame(mrg$keyword)
mrg$keyword <- NULL
mrg <- cbind(mrg, tmp)

  video_id col1 col2 bar baz blah foo yak
1        1  123  412   0   0    0   3   0
2        2  652  633   3   0    0   0   0
3        3  749  144   0   1    2   0   0
4        4 1738 1763   0   0    0   0   3

修改

这是另一种方式:

tt2 <- tapply(X = tab$keyword, INDEX = tab$video_id, FUN = table, simplify = FALSE)
video_ajdi <- factor(names(tt2))
tt2 <- cbind(video_id = video_ajdi, do.call("rbind", tt2))
mrg <- merge(data, tt2)
mrg

  video_id col1 col2 bar baz blah foo yak
1        1  123  412   0   0    0   3   0
2        2  652  633   3   0    0   0   0
3        3  749  144   0   1    2   0   0
4        4 1738 1763   0   0    0   0   3

EDIT2

还有一个:

tt <- aggregate(keyword ~ video_id, data = tab, FUN = table)
tt3 <- do.call("cbind", tt)
merge(data, tt3)

答案 1 :(得分:1)

这是一种方法,包括cbindmatch

数据:

df1 <- read.table(text="video_id  user_id keyword
1         1       foo
2         1       bar
3         1       baz
4         1       yak
1         2       foo
2         2       bar
3         2       blah
4         2       yak
1         3       foo
2         3       bar
3         3       blah
4         3       yak", header = TRUE)

tab <- table(df1[c("video_id", "keyword")])

        keyword
video_id bar baz blah foo yak
       1   0   0    0   3   0
       2   3   0    0   0   0
       3   0   1    2   0   0
       4   0   0    0   0   3


df2 <- read.table(text="video_id  col1  col2
1         123   412
2         652   633
3         749   144
4         1738  1763", header = TRUE)

以下是解决方案:

cbind(df2, tab[match(df2$video_id, rownames(tab)), ])

结果:

  video_id col1 col2 bar baz blah foo yak
1        1  123  412   0   0    0   3   0
2        2  652  633   3   0    0   0   0
3        3  749  144   0   1    2   0   0
4        4 1738 1763   0   0    0   0   3