所以,这就是我的数据框架:
Product_Code Publisher Published_Date
AB1F A 2011
AB1F (A Version) A 1999
TG1F (B Version) B 2001
AB1Z (A Version) A 2003
TG1F B 2006
GX1T C 2011
大约有130万行。
我要做的是对于具有相同Publisher的行,我会在Product_Code中使用grep()来查找具有相同Product Code的行,而不管它们是什么版本。并将它们设置为具有最早的Published_Date。
所以结果如下:
Product_Code Publisher Published_Date
AB1F A 1999
AB1F (A Version) A 1999
TG1F (B Version) B 2001
AB1Z (A Version) A 2003
TG1F B 2001
GX1T C 2011
我试过
for (n in 1:nrow(df)) {
A=which(grepl(df[n,1],df[,1])==TRUE & df[n,2]==df[,2])
min.date=min(df[A,3])
df[A,3]=min.date
}
我不确定这个for循环代码是否有效,因为我的计算机永远不会完成代码运行。
任何帮助将不胜感激!
答案 0 :(得分:3)
我们可以使用data.table
。转换' data.frame'到' data.table' (setDT(df1)
)。我们删除匹配空格的子字符串,后跟(
后跟一个使用sub
的字符,将其用作分组变量,if
中有(
个字符' Product_Code',然后我们match
' A',' B'使用' Product_Code'中的子字符串,删除NAs,使用它来对“已发布的时间”进行子集,获取min
或else
返回&# 39; Published_Date'并将(:=
)分配给' Published_Date'。
library(data.table)
setDT(df1)[, Published_Date := if(any(grep("\\(", Product_Code)))
min(Published_Date[na.omit(match(c("A", "B"), sub(".*\\((.).*", "\\1", Product_Code)))])
else Published_Date , by = .(grp=sub("\\s+.*", "", Product_Code))]
Product_Code Publisher Published_Date
#1: AB1F A 1999
#2: AB1F (A Version) A 1999
#3: TG1F (B Version) B 2001
#4: AB1Z (A Version) A 2003
#5: TG1F B 2001
#6: GX1T C 2011
或者使用dplyr
,separate
' Product_Code'分为两列("产品","版本"),按"产品"分组,我们mutate
' Published_Date'基于if/else
条件。
library(dplyr)
library(tidyr)
df1 %>%
separate(Product_Code, into = c("Product", "Version"), remove=FALSE) %>%
group_by(Product) %>%
mutate(Published_Date = if(all(is.na(Version))) Published_Date
else min(Published_Date[Version == Publisher & !is.na(Version)])) %>%
ungroup() %>%
select(-Product, - Version)
# Product_Code Publisher Published_Date
# <chr> <chr> <int>
#1 AB1F A 1999
#2 AB1F (A Version) A 1999
#3 TG1F (B Version) B 2001
#4 AB1Z (A Version) A 2003
#5 TG1F B 2001
#6 GX1T C 2011
我们也可以使用separate
来避免警告消息
extract
df1 %>%
extract(Product_Code, into = c("Product", "Version"),
"(\\S+)\\s*\\(*(\\S*).*", remove = FALSE)%>%
group_by(Product) %>%
mutate(Published_Date = if(all(!nzchar(Version))) Published_Date
else min(Published_Date[Version == Publisher])) %>%
ungroup() %>%
select(-Product, -Version)
# Product_Code Publisher Published_Date
# <chr> <chr> <int>
#1 AB1F A 1999
#2 AB1F (A Version) A 1999
#3 TG1F (B Version) B 2001
#4 AB1Z (A Version) A 2003
#5 TG1F B 2001
#6 GX1T C 2011
如果没有特定模式,我们可以为不具有(
并且包含1个以上字词的元素创建(
df1$Product_Code <- sub("\\s+\\(*", " (", df1$Product_Code)
并使用上述代码。