2016-10-13 58 views
0

编辑 我有如下一个数据框:请注意,COL1是有重复的条目,COL2 & COL3可以以任意顺序即它们可以在数据帧的其他列之间的任何地方发生...并且对在数据帧列的确切数目没有限制..有可能晚太所附附加列.....的R - 取决于多个条件组合数据帧行

COL1 COL2 COL3 COL5 COL6 COL7 ... ... (goes on) 
10 hai 2 15 10 6 ... ... 
10 hai 3 25 20 12 ... ... 
10 pal 1 35 30 18 ... ... 
11 rfm 9 22 32 9 ... ... 
    9 rtf 8 34 54 10 ... ... 

我也有如下的载体:

number <- c("first", "last") 

我所要的输出是这样的,如下图所示:即

  • COL1应该有单独的唯一项目(10,11,9)

  • COL2应包含其下的合并项没有重复项目(hai pal),不应将COL1值不同的唯一行用于合并。仅重复COL1值的行应该合并...和COL2可以在数据帧中的任何地方发生(它不会永远是第二列)

  • COL3应包含条目(总和2 + 3 + 1 = 6)。 单独计算重复行的总和。重复的行根据COL1值来标识...并且COL3也可以发生在数据框的任何地方(它不会总是第三列)。

而对于COL5COL6COL7(ⅰ可以具有许多的列后面所附...没有必要使我对这个条件仅3列)我需要一个广义一段代码,使得如果输入从名为“number”的向量中作为“第一个”给出时,需要从所有其余列的重复行中首次观察到的值,即第一行值。如果输入是从名为“number”的向量中作为“last”给出的,则需要从所有其余列的重复行中得到最后一次观察值,即最后一行值。

注:输出应被存储在另一数据帧

输出(如果输入被给定为 “第一”):

COL1 COL2 COL3 COL5 COL6 COL7 
10  hai pal 6 15 10 6 
11  rfm  9 22 32 9 
9  rtf  8 34 54 10 

在上面的输出:COL5,COL6, COL7包含重复条目的第一行值

输出(如果输入为“最后”):

COL1 COL2 COL3 COL5 COL6 COL7 
10  hai pal 6 15 10 6 
11  rfm  9 22 32 9 
9  rtf  8 34 54 10 

在上面的输出:COL5,COL6,COL7包含重复的条目

回答

2

的最后一行值可以使用dplyr

这基本上只是我上一个问题的comment的扩展。

library(dplyr) 
new_df <- df %>% group_by(COL1) %>% 
       summarise(COL2 = paste0(unique(COL2), collapse = " "), 
          COL3 = sum(COL3), 
          COL5 = first(COL5), 
          COL6 = first(COL6), 
          COL7 = first(COL7)) 
new_df 
# COL1 COL2  COL3 COL5 COL6 COL7 
# <int> <chr> <int> <int> <int> <int> 
#1 10 hai pal  6 15 10  6 

编辑

你可以使用last代替first同样的操作在dplyr

如果只有两个选项(第一,最后),您可以检查与条件if声明

if(number == "first") { 
    new_df <- df %>% group_by(COL1) %>% 
         summarise(COL2 = paste0(unique(COL2), collapse = " "), 
           COL3 = sum(COL3), 
           COL5 = first(COL5), 
           COL6 = first(COL6), 
           COL7 = first(COL7)) 
} else 
{ 
    new_df <- df %>% group_by(COL1) %>% 
         summarise(COL2 = paste0(unique(COL2), collapse = " "), 
           COL3 = sum(COL3), 
           COL5 = last(COL5), 
           COL6 = last(COL6), 
           COL7 = last(COL7)) 
} 
2

我们可以ü SE data.table

library(data.table) 
setDT(df1)[, .(COL2 = paste(unique(COL2), collapse= " "), 
       COL3 = sum(COL3), 
       COL5 = COL5[1L], 
       COL6 = COL6[1L], 
       COL7 = COL7[1L]), by = COL1] 
# COL1 COL2 COL3 COL5 COL6 COL7 
#1: 10 hai pal 6 15 10 6 

如果我们使用的data.table iev1.9.7的开发人员版本,那么这可以简化为

setDT(df1)[, c(COL2 = paste(unique(COL2), collapse=" "), 
      COL3 = sum(COL3) ,.SD[1L]), by = COL1, .SDcols=COL5:COL7] 
# COL1 COL2 COL3 COL5 COL6 COL7 
#1: 10 hai pal 6 15 10 6 

如果我们需要的最后一排,用.SD[.N]代替.SD[1L] ie

setDT(df1)[, c(COL2 = paste(unique(COL2), collapse=" "), 
    COL3 = sum(COL3) ,.SD[.N]), by = COL1, .SDcols=COL5:COL7] 
# COL1 COL2 COL3 COL5 COL6 COL7 
#1: 10 hai pal 6 35 30 18 

说明插件安装data.table的开发人员版本的here

+0

我无法安装v1.9.7,因为它在Rv3.2.1中不受支持....获取以下错误 – Rambo

+0

包'data.table'不可用(对于R版本3.2.1) – Rambo

+0

@Rambo这很奇怪。新的R版本是R 3.3.1。更新到新的R版本更好。 – akrun

1

与基础R试试这个:

get.df <- function(df, input) { 
    cbind.data.frame(COL1=unique(df$COL1), 
        COL2=paste(unique(df$COL2), collapse=' '), 
        COL3=sum(df$COL3), 
        df[ifelse(input == 'first', 1, nrow(df)),names(df)[-1:-3]]) 
} 

get.df(df, 'first') 
# COL1 COL2 COL3 COL5 COL6 COL7 
# 1 10 hai pal 6 15 10 6 

get.df(df, 'last') 
# COL1 COL2 COL3 COL5 COL6 COL7 
# 3 10 hai pal 6 35 30 18 

根据您的新的要求,试试这个:

df <- read.table(text='COL1 COL2 COL3 COL5 COL6 COL7 
       10 hai 2 15 10 6 
       10 hai 3 25 20 12 
       10 pal 1 35 30 18 
       11 rfm 9 22 32 9 
        9 rtf 8 34 54 10', header=TRUE) 

get.df <- function(df, input) { 

    dups <- unique(df[duplicated(df$COL1),]$COL1) 
    df.dup <- df[df$COL1 %in% dups,] 
    df.nondup <- df[!(df$COL1 %in% dups),] 
    rbind(cbind.data.frame(COL1=unique(df.dup$COL1), 
        COL2=paste(unique(df.dup$COL2), collapse=' '), 
        COL3=sum(df.dup$COL3), 
        df.dup[ifelse(input == 'first', 1, nrow(df.dup)),names(df.dup)[-1:-3]]), 
     df.nondup) 
} 

number <- c("first", "last") 

get.df(df, 'first') 

COL1 COL2 COL3 COL5 COL6 COL7 
1 10 hai pal 6 15 10 6 
4 11  rfm 9 22 32 9 
5 9  rtf 8 34 54 10 

get.df(df, 'last') 

COL1 COL2 COL3 COL5 COL6 COL7 
3 10 hai pal 6 35 30 18 
4 11  rfm 9 22 32 9 
5 9  rtf 8 34 54 10 
+0

我觉得这个答案有用。但一个小改动。即使COL1中存在非重复值,我也需要上述代码才能正常工作,即我需要仅对输入df中的重复行进行上述操作。对于非重复行,我不希望发生任何操作。我编辑了这个问题 – Rambo

+0

您是否希望返回输出数据框中的非重复COL1值的行,或放弃它们? –

+0

请现在阅读这个问题。希望现在澄清 – Rambo