我有条件从两个数据文件添加某些列的问题。 例如,我有这个数据文件:
数据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做同样的事情......我想我的方法错了,感谢任何帮助!我希望这是有道理的。先感谢您。
答案 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)
使用dplyr
和magrittr
:
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))