从我原来的观察......
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
列位于表格数据和原始数据之间,因此顺序不正确。
答案 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)
这是一种方法,包括cbind
和match
:
数据:
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