我试图弄清楚如何连接2个数据帧以创建数据的垂直表。这是一些示例数据:
people <- data.frame(person = c("John","David","Peter"), company = c("A", "B", "C"))
grades <- data.frame(person1=c(10, 40, 50, 60), person2=c(60,70,80, 100), person3=c(33,44,55, 75))
注意:grades
中的列顺序与person
数据框中的people
列的顺序相同。
我想得到一个像下面这样的数据框,但是不知道如何到达那里。希望使用基于R的解决方案(因为我使用的是R的较旧版本,因此某些软件包对我不起作用):
person | company | grade
-------------------------
John | A | 10
John | A | 40
John | A | 50
John | A | 60
David | B | 60
David | B | 70
David | B | 80
David | B | 100
Peter | C | 33
Peter | C | 44
Peter | C | 55
Peter | C | 75
答案 0 :(得分:4)
我们将“人”列的“等级”列名称从“人” gather
更改为“长”格式,然后执行left_join
library(tidyverse)
setNames(grades, people$person) %>%
gather(person, grade) %>%
left_join(people)
# person grade company
#1 John 10 A
#2 John 40 A
#3 John 50 A
#4 John 60 A
#5 David 60 B
#6 David 70 B
#7 David 80 B
#8 David 100 B
#9 Peter 33 C
#10 Peter 44 C
#11 Peter 55 C
#12 Peter 75 C
或将base R
与merge
一起使用
merge(stack(setNames(grades, people$person)),
people, all.x = TRUE, by.x = 'ind', by.y = 'person')
答案 1 :(得分:2)
使用cbind
的基本R选项为
idx <- rep(seq_along(people$person), each = dim(grades)[1])
cbind(people[idx,], stack(unlist(grades))["values"])
结果
# person company values
#1 John A 10
#1.1 John A 40
#1.2 John A 50
#1.3 John A 60
#2 David B 60
#2.1 David B 70
#2.2 David B 80
#2.3 David B 100
#3 Peter C 33
#3.1 Peter C 44
#3.2 Peter C 55
#3.3 Peter C 75
在unlist
上使用stack
和grades
来获得
stack(unlist(grades))
values ind
1 10 john_grades1
2 40 john_grades2
3 50 john_grades3
4 60 john_grades4
5 60 david1
6 70 david2
7 80 david3
8 100 david4
9 33 pj1
10 44 pj2
11 55 pj3
12 75 pj4
因为“等级中列的顺序与人员数据框中人员列的顺序相同。”在扩展cbind
使其具有正确的行数之后,接下来可以使用people
。
(idx <- rep(seq_along(people$person), each = dim(grades)[1]))
# [1] 1 1 1 1 2 2 2 2 3 3 3 3
另一种选择,可能会更快一点
cbind(people[idx,], data.frame(grade = unlist(grades, use.names = FALSE)))