修改
我有一个如下数据框:请注意COL1
有重复的条目,COL2& COL3可以按任何顺序排列,即它们可以出现在数据帧中其他列之间的任何位置......并且对数据帧中的确切列数没有限制。以后可能还会添加其他列..... / p>
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)。应该仅为重复行计算 Sum。基于COL1值识别重复行...并且COL3也可以出现在数据框中的任何位置(它不会总是第3列)。
对于COL5
,COL6
,COL7
(我可能会在后面添加许多列...不需要我只有3列用于此条件)我需要一个广义的片段例如,如果输入从名为“number”的向量中给出为“first”,则需要从所有剩余列的重复行中获取第一次观察的值,即第一行值。如果输入从名为“number”的向量中作为“last”给出,则需要从所有剩余列的重复行中进行最后一次观察的值,即最后一行值。
注意:输出应存储在另一个数据帧
中OUTPUT(如果输入为“first”):
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包含重复条目的第一行值
OUTPUT(如果输入为“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包含重复条目的最后一行值
答案 0 :(得分: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))
}
答案 1 :(得分:2)
我们可以使用Column2
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
的devel版本,即v.1.9.7,那么这可以简化为
data.table
如果我们需要最后一行,请使用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]
安装devel版本的data.table的说明是here
答案 2 :(得分: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