R 将一个数据帧中的列合并到新数据帧中,并进行筛选

R 将一个数据帧中的列合并到新数据帧中,并进行筛选,r,R,我有一个上面的数据框。我需要根据2017年3月17日第一次出现的日期设置如下框架。所以我需要低于输出 Material DocDate Name Address Unit Price 1258486 3/17/2017 FEHLIG BROS BOX asd 8.95 1258486 5/11/2017 FEHLIG BROS BOX asd 9.5 1258486 12/11/2017 FEHLIG BROS_BOX

我有一个上面的数据框。我需要根据2017年3月17日第一次出现的日期设置如下框架。所以我需要低于输出

Material    DocDate    Name  Address    Unit    Price
1258486   3/17/2017   FEHLIG BROS BOX    asd     8.95
1258486   5/11/2017   FEHLIG BROS BOX    asd     9.5
1258486   12/11/2017  FEHLIG BROS_BOX    asd     10.5
1250000   12/20/2017  Krones ALPHA       afg     11.5
使用data.table,您可以尝试

Material         Name/address/Unit Price
1258486     FEHLIG BROS BOX/asd/8.95/9.5/10.5
1250000     Krones/ALPHA/afg/11.5

根据对您的问题所做的更改进行完整编辑:

df <- read.table(stringsAsFactors = FALSE, header = TRUE,
                 text ="Material DocDate Name  Address Unit  Price
                 1258486   3/17/2017  FEHLIG BROS_BOX     asd     8.95
                 1258486   5/11/2017  FEHLIG BROS_BOX     asd     9.5
                 1258486   12/11/2017  FEHLIG BROS_BOX    asd     10.5
                 1250000   12/20/2017  Krones ALPHA       afg     11.5
                 ")
df$DocDate <- as.Date(df$DocDate,'%m/%d/%Y')
library(data.table)
setDT(df)[,.(newVar = paste(Name, Address, Unit, paste(.SD$Price,collapse = "/"), sep = "/") )
          ,by = Material][,.(newVar = newVar[1]), Material]

#returns
   Material                            newVar
1:  1258486 FEHLIG/BROS_BOX/asd/8.95/9.5/10.5
2:  1250000             Krones/ALPHA/afg/11.5

这里有一个使用dplyr的替代方法。首先是样本数据:

# create example data (notice this differs slightly from your table above)
df <- read.csv(stringsAsFactors = FALSE, header = TRUE,
                 text ="Material, DocDate, Name, Address, UnitPrice
                        1258486, 3/17/2017, FEHLIG BROS BOX, asd, 8.95
                        1258486, 5/11/2017, FEHLIG BROS BOX, asd, 9.50
                        1258486, 12/11/2017, FEHLIG BROS_BOX, asd, 10.5
                        1250000, 12/20/2017, Krones ALPHA, afg, 11.5")

# let's use data.table
library(data.table)
df_orig <- as.data.table(df)
df_orig[ , DocDate := as.Date(DocDate,format="%m/%d/%Y")][order(DocDate)]

# create one string per Name-Material pair
df_intermed <- df_orig[ , .(newvar = paste(Name[1], Address[1], paste(UnitPrice, collapse="/"), sep="/")), by=.(Material, Name)]

# aggregate those strings across Names, so one row per Material
df_final <- df_intermed[ , .(newvar = paste(newvar, collapse=",")), by=Material]

编辑:代码中的固定打字错误

是关于生成将名称/地址/单位/价格组合到一个字段中的新数据框的问题吗?粘贴名称、地址、单位、价格、sep=/应该有帮助。你想要第一行,还是按日期排序?@Jon spring。是的,你是对的。我建议包括更多的案例行,因为可能有很多可能的答案。此外,最好在数据框的变量名中排除“和”和空格。虽然可以编辑,以便删除你认为机密的信息,而在可理解的条件下留下你的问题和答案,但是你需要小心地这样做,这样你就不会破坏问题和答案的价值。如果它是真正的机密信息,并且问题/答案在没有它的情况下仍然有价值,那么一旦您进行了编辑,您就可以,然后,您可以标记版主注意,要求编辑旧版本,即实际删除旧版本,以便查看编辑历史记录的人不再看到旧版本。鼓励编辑问题以改进旧版本,例如澄清等。但是,编辑问题以使其更改,从而使答案无效,这是违反堆栈溢出策略的。你在这里的编辑是这样做的。政策是其他用户应主动恢复此类更改。我在这里已经这样做了。我们鼓励您这样做,也许您可以通过链接了解更多的上下文。我们想提供帮助,但您的新/附加问题需要是一个新问题。考虑到这一点和您的新问题,我编辑了答案data@Makyen非常感谢您带回我的解决方案,我在上次编辑中错误地单击了“批准”。@Makyen是的,我以为我批准了拒绝,然而,我马上检查了一下,这是他的编辑,我批准了。再次感谢你。我刚刚注意到OP也改变了最初的数据,所以sad是在玩问题游戏。评论不是为了扩大讨论;这段对话已经结束了。嗨,丹,这种约会还是不起作用。还在约会吗
data <- data.frame(stringsAsFactors=FALSE,
                   Material   = c(1258486L, 1258486L),
                   DocDate    = c("3/17/2017", "5/11/2017"),
                   Name       = c("FEHLIG BROS BOX", "FEHLIG BROS BOX"),
                   Address    = c("asd", "asd"),
                   Unit_Price = c(8.95, 9.5))
library(dplyr)
output <- data %>%

  # convert DocDate to a date
  mutate(DocDate = as.Date(DocDate,'%m/%d/%Y')) %>%

  # For each Material...
  group_by(Material) %>% 

  # just keep the line(s) with the first date...
  filter(DocDate == min(DocDate)) %>% ungroup() %>% 

  # and combine fields
  mutate(`Name/address/Unit Price` = paste(Name, Address, Unit_Price, sep = "/")) %>%

  # just the requested columns
  select(Material, `Name/address/Unit Price`)

output
# A tibble: 1 x 2
  Material `Name/address/Unit Price`
     <int> <chr>                    
1  1258486 FEHLIG BROS BOX/asd/8.95