Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 在数据帧中创建一个新变量,条件位于另一个数据帧上_R_Dataframe_Data.table_Sqldf - Fatal编程技术网

R 在数据帧中创建一个新变量,条件位于另一个数据帧上

R 在数据帧中创建一个新变量,条件位于另一个数据帧上,r,dataframe,data.table,sqldf,R,Dataframe,Data.table,Sqldf,我有两个这样的数据帧 df1 df2 目的 prm变量是一个常量变量,它只有1个值。 我想用这个条件在我的df1中添加变量prm df1$date is between df2$date1 and df2$date2 and df1$item=df2$item 但是,如果条件不匹配,那么我需要prm获取值NO,您可以在这里使用ifelse 你可以在这里用ifelse 以下是使用dplyr的解决方案: library(tidyverse) df1 = tribble(~date, ~item,

我有两个这样的数据帧

df1

df2

目的

prm变量是一个常量变量,它只有1个值。 我想用这个条件在我的df1中添加变量prm

df1$date is between df2$date1 and df2$date2 and df1$item=df2$item
但是,如果条件不匹配,那么我需要prm获取值NO

,您可以在这里使用ifelse

你可以在这里用ifelse


以下是使用dplyr的解决方案:

library(tidyverse)

df1 = tribble(~date, ~item,
             "02/01/2017",    "A",
             "09/01/2017",    "B",
             "16/01/2017",    "C")

df2 = tribble(~date1, ~date2, ~item,
"01/01/2017",  "03/01/2017",     "A",
"08/01/2017",  "10/01/2017",     "B",
"15/01/2017",  "15/01/2017",     "C")

df3 = merge(x = df1, y = df2)


df4 = as.data.frame(cbind(df3[1], lapply(df3[2:4], as.Date, format = "%d/%m/%Y")))


df5 <- df4 %>%
  mutate(prm = if_else((date > date1) & (date < date2), "YES", "NO"))

df5

以下是使用dplyr的解决方案:

library(tidyverse)

df1 = tribble(~date, ~item,
             "02/01/2017",    "A",
             "09/01/2017",    "B",
             "16/01/2017",    "C")

df2 = tribble(~date1, ~date2, ~item,
"01/01/2017",  "03/01/2017",     "A",
"08/01/2017",  "10/01/2017",     "B",
"15/01/2017",  "15/01/2017",     "C")

df3 = merge(x = df1, y = df2)


df4 = as.data.frame(cbind(df3[1], lapply(df3[2:4], as.Date, format = "%d/%m/%Y")))


df5 <- df4 %>%
  mutate(prm = if_else((date > date1) & (date < date2), "YES", "NO"))

df5
[编辑]

如果df1和df2中的行数不同,可以使用sqldf并在df2.date1和df2.date2之间的df1.date上创建一个左联接,df1.item=df2.item并使用case WHEN语句创建列prm:

[编辑]

如果df1和df2中的行数不同,可以使用sqldf并在df2.date1和df2.date2之间的df1.date上创建一个左联接,df1.item=df2.item并使用case WHEN语句创建列prm:

使用data.table中可用的非相等联接和联接时更新,这将变为:

library(data.table)
setDT(df1)[setDT(df2), on = .(item, date>=date1, date<= date2), prm := i.prm][
  is.na(prm), prm := "NO"]
df1
使用data.table中可用的非相等联接和联接时更新,这将变为:

library(data.table)
setDT(df1)[setDT(df2), on = .(item, date>=date1, date<= date2), prm := i.prm][
  is.na(prm), prm := "NO"]
df1

这是一个简单的非等连接data.table我尝试了data.table,但是我的df从180万行传递到80万行不知道为什么,因为当我做一个unique时,我仍然有180万行stry librarydata.table;setDTdf1[setDTdf2,on=.item,date>=date1,date Nice谢谢它和所有的解决方案一样工作正常这是一个简单的数据非均衡连接。table我尝试了data.table,但是我的df从1800000行传递到800000行不知道为什么,因为当我做一个unique时,我仍然有1800000行stry librarydata.table;setDTdf1[setDTdf2,on=.item,date>=date 1,date Nice谢谢,它和所有解决方案一样工作正常是的,但我认为我的解释不够好,我会编辑我的问题,或者回答中有什么遗漏吗?0002-01-20对你来说像是一个有效的日期吗?这应该是df1$date是的,但我认为我的解释是正确的不够好,我将编辑我的问题。答案中是否缺少任何内容?0002-01-20对您来说是有效的日期吗?这应该是df1$date,但与数据相同。表我不知道为什么,在sqldf之前,我的数据帧有180万行,在它有80万行之后是它,因为只有80万行符合日期aND项条件?我已将联接更改为左联接,这就是您要寻找的吗?它可以工作,但问题与data.table相同。我不知道为什么,在sqldf之前,我的数据帧有180万行,而在它之后有80万行是因为只有80万行符合日期和项条件?我已将联接更改为左联接,这是什么你在找什么?
options("stringsAsFactors" = FALSE)

df1 <- read.table(text = 
"date item 
02/01/2017    A 
09/01/2017    B
16/01/2017    C 
02/01/2017    C",
header = TRUE)
df2 <- read.table(text =
"date1       date2  item
01/01/2017  03/01/2017     A 
08/01/2017  10/01/2017     B
15/01/2017  17/01/2017     C",
header = TRUE)

library(sqldf)


sqldf("
  SELECT df1.*, CASE WHEN df1.item = df2.item THEN 'yes' ELSE 'no' END AS prm
  FROM df1 
  LEFT JOIN df2 
   ON df1.date BETWEEN df2.date1 AND df2.date2
   AND df1.item = df2.item
  ")

        date item prm
1 02/01/2017    A yes
2 09/01/2017    B yes
3 16/01/2017    C yes
4 02/01/2017    C  no
library(data.table)
setDT(df1)[setDT(df2), on = .(item, date>=date1, date<= date2), prm := i.prm][
  is.na(prm), prm := "NO"]
df1
         date item prm
1: 2017-01-02    A YES
2: 2017-01-09    B YES
3: 2017-01-14    C  NO