R 按列和行合并数据帧
我有一个共享相似方面的两个数据集,例如数据集aR 按列和行合并数据帧,r,merge,row,R,Merge,Row,我有一个共享相似方面的两个数据集,例如数据集a name year region Jane 1980 1 Jane 1981 2 Mike 1980 1 Mike 1985 4 Bob 1980 NA Bob 1981 1 和数据集B year 1 2 3 4 5 1980 12 44 76 108 140 1981 55 77 99 121 143 1982
name year region
Jane 1980 1
Jane 1981 2
Mike 1980 1
Mike 1985 4
Bob 1980 NA
Bob 1981 1
和数据集B
year 1 2 3 4 5
1980 12 44 76 108 140
1981 55 77 99 121 143
1982 56 76 96 116 136
1983 56 43 30 17 4
我想在第一个数据集中创建一个名为“income
”的新列,它根据年份和第1-5列合并第二个数据集中的数字。例如,由于1980年鲍勃在第5区,相应的收入将为140。如果没有匹配项,我希望income
成为NA
到目前为止我试过了
which(A$year==B$year & A$region==rownames(B)[2:6])
但我认为这不管用
我还想补充的是,并非所有数据点都匹配,数据集A中的区域变量都有NAs,数据集B中的年数并不涵盖数据集A中的所有年份。您只需要将第二个数据集的格式从宽格式转换为长格式。使用重塑2和plyr可以非常轻松地完成此操作:
library(reshape2)
library(plyr)
b <- read.table(text = "year 1 2 3 4 5
1980 12 44 76 108 140
1981 55 77 99 121 143
1982 56 76 96 116 136
1983 56 43 30 17 4",header = TRUE,sep = "",check.names = FALSE)
a <- read.table(text = "name year region
Jane 1980 1
Jane 1981 2
Mike 1980 1
Mike 1981 4
Bob 1980 5
Bob 1981 1",header = TRUE,sep = "")
b <- melt(b,id.vars = "year")
b <- rename(b,c("variable" = "region"))
merge(a,b,all.x = TRUE)
library(重塑2)
图书馆(plyr)
b您只需要将第二个数据集从宽格式转换为长格式。使用重塑2和plyr可以非常轻松地完成此操作:
library(reshape2)
library(plyr)
b <- read.table(text = "year 1 2 3 4 5
1980 12 44 76 108 140
1981 55 77 99 121 143
1982 56 76 96 116 136
1983 56 43 30 17 4",header = TRUE,sep = "",check.names = FALSE)
a <- read.table(text = "name year region
Jane 1980 1
Jane 1981 2
Mike 1980 1
Mike 1981 4
Bob 1980 5
Bob 1981 1",header = TRUE,sep = "")
b <- melt(b,id.vars = "year")
b <- rename(b,c("variable" = "region"))
merge(a,b,all.x = TRUE)
library(重塑2)
图书馆(plyr)
这是另一种选择,因为乔兰让我工作
创建收入的矩阵
b <- as.matrix(B[-1])
rownames(b) <- B[,1]
我们可以使用它从矩阵“b”中提取相关数据,并将其添加到原始的data.frame
A$income <- b[cbind(match(A$year, rownames(b)), A$region)]
A
# name year region income
# 1 Jane 1980 1 12
# 2 Jane 1981 2 77
# 3 Mike 1980 1 12
# 4 Mike 1981 4 121
# 5 Bob 1980 5 140
# 6 Bob 1981 1 55
A$income这里有一个替代方案,因为Joran让我工作
创建收入的矩阵
b <- as.matrix(B[-1])
rownames(b) <- B[,1]
我们可以使用它从矩阵“b”中提取相关数据,并将其添加到原始的data.frame
A$income <- b[cbind(match(A$year, rownames(b)), A$region)]
A
# name year region income
# 1 Jane 1980 1 12
# 2 Jane 1981 2 77
# 3 Mike 1980 1 12
# 4 Mike 1981 4 121
# 5 Bob 1980 5 140
# 6 Bob 1981 1 55
A$income既然joran和Ananda选择了所有好的选择,这里有一个荒谬的选择:
a$income <-
mapply(function(ro,co) b[ro,co], match(a$year,b$year), as.character(a$region))
# name year region income
#1 Jane 1980 1 12
#2 Jane 1981 2 77
#3 Mike 1980 1 12
#4 Mike 1981 4 121
#5 Bob 1980 5 140
#6 Bob 1981 1 55
a$income既然joran和Ananda选择了所有好的选择,这里有一个荒谬的选择:
a$income <-
mapply(function(ro,co) b[ro,co], match(a$year,b$year), as.character(a$region))
# name year region income
#1 Jane 1980 1 12
#2 Jane 1981 2 77
#3 Mike 1980 1 12
#4 Mike 1981 4 121
#5 Bob 1980 5 140
#6 Bob 1981 1 55
a$income这是我在过去几周内第三次尝试为数据转换问题提供sqldf
解决方案。还没有爱情。我们将看看人们这次是怎么想的
使用Joran回答中的数据:
require(sqldf)
sqldf('select
a.name
,a.year
,a.region
,case
when region = 1 then b.X1
when region = 2 then b.X2
when region = 3 then b.X3
when region = 4 then b.X4
when region = 5 then b.X5
end income
from a
join b
on a.year= b.year')
在这里,我使用标准的SQL case语句“融化”数据
sqldf
确实要求我在b
中的区域列前面加一个X,因为在包下运行的数据库引擎强制使用非整数字段名 这是我在过去几周内第三次尝试为数据转换问题提供sqldf
解决方案。还没有爱情。我们将看看人们这次是怎么想的
使用Joran回答中的数据:
require(sqldf)
sqldf('select
a.name
,a.year
,a.region
,case
when region = 1 then b.X1
when region = 2 then b.X2
when region = 3 then b.X3
when region = 4 then b.X4
when region = 5 then b.X5
end income
from a
join b
on a.year= b.year')
在这里,我使用标准的SQL case语句“融化”数据
sqldf
确实要求我在b
中的区域列前面加一个X,因为在包下运行的数据库引擎强制使用非整数字段名 你能不能再详细说明一下熔体的作用以及“变量”=“区域”的含义?我尝试了melt命令,但它没有改变任何东西。@Rusuer9000,melt
将数据转换为“长”形式“variable”=“region”
只需将当您将数据.帧
融化为“region”时创建的“variable”变量重命名为“region”。Joran,您可以通过使用melt
中的variable.name
参数melt(b,id.vars=“year”,variable.name=“region”)来避免仅为重命名而加载包
。您能否详细说明一下melt的作用以及“变量”=“区域”的含义?我尝试了melt命令,但它没有改变任何东西。@Rusuer9000,melt
将数据转换为“长”形式“variable”=“region”
只需将当您将数据.帧
融化为“region”时创建的“variable”变量重命名为“region”。Joran,您可以通过使用melt
中的variable.name
参数melt(b,id.vars=“year”,variable.name=“region”)来避免仅为重命名而加载包
。我想你是在使用我的答案和@joran的答案中的数据,但是+1:-)我的观点是,当你的mapply
指的是a/b
时,你把它分配给了一个名为a
的对象……哦,积垢球。。。你必须对我更明确一点——这是漫长的一年!;-)您好,我对我的问题进行了一些编辑-我认为在执行cbind?@Rusuer9000之后,当存在NAs时,该代码不起作用-joran的答案将适用于NA值。我的,不太多。我想你使用的是我的答案和@joran的答案中的数据,但是+1:-)我的观点是,当你的mapply
指的是a/b
,你把它分配给了一个名为a
的对象……哦,积垢球。。。你必须对我更明确一点——这是漫长的一年!;-)您好,我对我的问题进行了一些编辑-我认为在执行cbind?@Rusuer9000之后,当存在NAs时,该代码不起作用-joran的答案将适用于NA值。我的,没那么多。非常感谢你的代码!但我有一个问题——因为不是所有的数据点都匹配,所以在我对整个数据集执行cbind(匹配(A$year,rownames(b)),A$region)之后,会有很多NAs,当我尝试从b中提取时,会出现一个错误“下标超出范围”。有没有办法提取我找到的答案,但将其余部分保留为NAs?@Rusuer9000,即使你编辑了我的答案和Joran的作品。您是否可以重新创建一个小数据集(以可复制的方式,就像我们在这些答案中所做的那样)来演示问题/错误?谢谢。我解决了这个问题——在进行cbind之后的矩阵是一个字符矩阵,在从b中提取之前,我必须将其转换为数字。非常感谢。非常感谢这段代码!但我有一个问题——因为不是所有的数据点都匹配,所以在我对整个数据集执行cbind(匹配(A$year,rownames(b)),A$region)之后,会有很多NAs,当我尝试从b中提取时,会出现一个错误“下标超出范围”。会有一个w吗