R 从两个数据文件中有条件地添加某些数据列
我对有条件地从两个数据文件中添加特定列有一个问题。 例如,我有一个数据文件: 数据1R 从两个数据文件中有条件地添加某些数据列,r,R,我对有条件地从两个数据文件中添加特定列有一个问题。 例如,我有一个数据文件: 数据1 ID purchased 1 5 2 3 3 3 4 3 5 3 6 4 7 4 8 4 9 4 10 4 数据2 ID Date3 Date4 Date5 1 2014 2013 2017 2 2014 2015 2012 3 2013 2016 2014 4 2015 2017 2014 5
ID purchased
1 5
2 3
3 3
4 3
5 3
6 4
7 4
8 4
9 4
10 4
数据2
ID Date3 Date4 Date5
1 2014 2013 2017
2 2014 2015 2012
3 2013 2016 2014
4 2015 2017 2014
5 2016 2012 2017
6 2017 2013 2017
7 2012 2013 2012
8 2014 2013 2014
9 2014 2015 2014
10 2015 2016 2015
因此,在这两个文件中,purchase列(数据1)上的数字链接到特定日期。例如,ID1购买5(数据1)应链接到ID1日期5(数据2);ID2购买了ID2 Date3(数据2)等的3个链接,因此结果如下所示
结果:
ID purchased Date
1 5 2017
2 3 2014
3 3 2013
4 3 2015
5 3 2016
6 4 2013
7 4 2013
8 5 2014
9 5 2014
10 4 2016
我正在考虑使用如下的夫妇if语句:
if ((Data1$ID== Data2$ID) & Data1$purchased ==3) {
Data1$Date<- Data2$Date3
}
if((Data1$ID==Data2$ID)&Data1$purchased==3){
Data1$Date也许有一种更漂亮的方法,但您可以这样做:
Data1$Date <- ifelse(Data1$purchased==3,Data2$Date3,ifelse(Data1$purchased==4,Data2$Date4,Data2$Date5))
Data1$Date如果您的日期列顺序是以恒定的升序排列,您可以尝试:
k = Data1$purchased-1
Data1$year = sapply(seq_along(k),function(x) Data2[x,k[x]])
或者,如果要按列名匹配:
k = match(Data1$purchased,as.numeric(gsub("Date","",colnames(Data2)[-1],fixed=TRUE)))
Data1$year = sapply(seq_along(k),function(x) Data2[x,k[x]+1])
如果两个数据帧中ID的顺序不同,则此操作也有效:
df$Date = sapply(1:nrow(df), function(x)
df1[df1$ID==df$ID[x],paste0("Date",df$purchased[x])])
输出:
ID purchased Date
1 1 5 2017
2 2 3 2014
3 3 3 2013
4 4 3 2015
5 5 3 2016
6 6 4 2013
7 7 4 2013
8 8 4 2013
9 9 4 2015
10 10 4 2016
数据:
使用dplyr
和magrittr
:
- 我们首先更改
data1
中的purchased
列值,使其与data2
- 然后我们使用
map2
获得正确的元素,更具体地说,map2\u int
将向量作为输出
- 然后我们将这个向量附加到
data2
代码:
或者稍微短一点,也许更令人满意,因为我们没有中途回复数据1:
data1 %>%
mutate(d=paste0("Date",purchased)) %$%
mutate(.,Date = map2_int(ID,d, ~ data2[.x,.y])) %>%
select(-d)
和一艘班轮:
data1 %$% mutate(.,Date = map2(ID,purchased, ~ data2[.x,grep(.y,names(data2))]))
结果:
# ID purchased Date
# 1 1 5 2017
# 2 2 3 2014
# 3 3 3 2013
# 4 4 3 2015
# 5 5 3 2016
# 6 6 4 2013
# 7 7 4 2013
# 8 8 4 2013
# 9 9 4 2015
# 10 10 4 2016
这里有两种方法
方法1,baseR-通过匹配进行矢量化
df$Date <- diag(as.matrix(df1[match(df$purchased, sort(unique(df$purchased)))+1]))
都是给予,
这是一个基本的R答案,类似于使用矩阵提取的soto的答案
dat1$Date <- dat2[cbind(match(dat1$ID, dat2$ID), dat1$purchased - 1)]
我们还可以在第二个参数中使用match
,找到dat2中变量名的最后一个字符与dat1中购买的变量值的匹配索引。这可能更灵活
dat1$Date <- dat2[cbind(match(dat1$ID, dat2$ID),
match(as.character(dat1$purchased),
substring(names(dat2), nchar(names(dat2)))))]
dat1$Date请注意,您的示例结果在值8和9的最后一列中是错误的
library(tidyverse)
df1 %>%
gather(var, val, -ID) %>%
left_join(mutate(df, purchased = paste0('Date', purchased)), .,
by = c('ID' = 'ID', 'purchased' = 'var')) %>%
mutate(purchased = gsub('\\D+', '', purchased))
ID purchased Date
1 1 5 2017
2 2 3 2014
3 3 3 2013
4 4 3 2015
5 5 3 2016
6 6 4 2013
7 7 4 2013
8 8 4 2013
9 9 4 2015
10 10 4 2016
dat1$Date <- dat2[cbind(match(dat1$ID, dat2$ID), dat1$purchased - 1)]
dat1
ID purchased Date
1 1 5 2017
2 2 3 2014
3 3 3 2013
4 4 3 2015
5 5 3 2016
6 6 4 2013
7 7 4 2013
8 8 4 2013
9 9 4 2015
10 10 4 2016
dat1$Date <- dat2[cbind(match(dat1$ID, dat2$ID),
match(as.character(dat1$purchased),
substring(names(dat2), nchar(names(dat2)))))]
dat1 <-
structure(list(ID = 1:10, purchased = c(5L, 3L, 3L, 3L, 3L, 4L,
4L, 4L, 4L, 4L)), .Names = c("ID", "purchased"), row.names = c(NA,
-10L), class = "data.frame")
dat2 <-
structure(list(ID = 1:10, Date3 = c(2014L, 2014L, 2013L, 2015L,
2016L, 2017L, 2012L, 2014L, 2014L, 2015L), Date4 = c(2013L, 2015L,
2016L, 2017L, 2012L, 2013L, 2013L, 2013L, 2015L, 2016L), Date5 = c(2017L,
2012L, 2014L, 2014L, 2017L, 2017L, 2012L, 2014L, 2014L, 2015L
)), .Names = c("ID", "Date3", "Date4", "Date5"), class = "data.frame",
row.names = c(NA, -10L))