R 从两个数据文件中有条件地添加某些数据列

R 从两个数据文件中有条件地添加某些数据列,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

我对有条件地从两个数据文件中添加特定列有一个问题。 例如,我有一个数据文件:

数据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   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))