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

时间:2017-08-11 07:57:18

标签: 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   2016    2012    2017
6   2017    2013    2017
7   2012    2013    2012
8   2014    2013    2014
9   2014    2015    2014
10  2015    2016    2015

因此,在这两个文件中,购买列(数据1)上的数字链接到特定日期。例如,购买的ID 1(数据1)应链接到ID 1 Date5(数据2); ID 2购买3个链接到ID 2 Date3(数据2)等。所以结果如下所示。

结果:

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  
} 

对购买的4和5做同样的事情......我想我的方法错了,感谢任何帮助!我希望这是有道理的。先感谢您。

5 个答案:

答案 0 :(得分:2)

也许有一种更美丽的方式,但你可以这样做:

3000

条件是您的ID已排序,因此您无需在Data1$Date <- ifelse(Data1$purchased==3,Data2$Date3,ifelse(Data1$purchased==4,Data2$Date4,Data2$Date5)) 语句中的ID上插入条件。

答案 1 :(得分:2)

如果您的日期列的顺序按升序排列,您可以尝试:

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])

答案 2 :(得分:2)

以下是两种方法,

方法1,baseR - 通过匹配进行矢量化

df$Date <- diag(as.matrix(df1[match(df$purchased, sort(unique(df$purchased)))+1]))

方法2,tidyverse - 加入

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

答案 3 :(得分:0)

使用dplyrmagrittr

  • 我们首先更改purchased中的data1列值,使其与data2
  • 的列匹配
  • 然后我们使用map2来获取正确的元素,更具体地说map2_int将矢量作为输出,
  • 然后我们将此向量附加到data2

代码:

library(magrittr)
library(dplyr)
data1 %>%
  mutate(purchased=paste0("Date",purchased)) %$%
  map2_int(ID,purchased, ~ data2[.x,.y]) %>%
  cbind(data1,.) %>%
  rename_("Date"= ".")

或者更短,可能更令人满意,因为我们不会中途重新插入数据:

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

答案 4 :(得分:0)

这是一个类似于使用矩阵提取的soto的基本R答案。

dat1$Date <- dat2[cbind(match(dat1$ID, dat2$ID), dat1$purchased - 1)]

在这里,我们使用矩阵来索引dat2内部的值,即日期列。我们首先匹配dat1中的ID以选择正确的行,然后使用dat2中列的位置,以便通过减法提取正确的列。

返回

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

我们还可以在第二个参数中使用match来查找dat2中变量名的最后一个字符的匹配索引,以及dat1中购买变量的值。这可能更灵活。

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