从行中的值中删除重复项

时间:2016-05-26 13:16:36

标签: r dataframe duplicates

我有一个尺寸为58000 * 900的df,它包含行值的重复,我想遍历每一行并删除它们。一个例子将使它更清楚。

df
IDs Name    col1    col2    col3
123 AB.C    1.3,1.3,1.3,1.3,1.3 0,0,0,0,0   5,5,5,5,5
234 CD-E    2,2,2,2,2   0.3,0.3,0.3,0.3,0.3 1,1,1,1,1
568 GHJ 123456      123456              123456
345 FGH 9,9,9,9,9   54,54,54,54,54  0,0,0,0,0

显然每个值都被复制5次,在某些情况下,它们是一个问题,即没有.,分隔值。 我想要的是丢弃那些不包含.,的行,其余的则删除重复的值。所以,输出将是:

IDs Name    col1    col2    col3
123 AB.C    1.3 0   5
234 CD-E    2   0.3 1
345 FGH 9   54  0

dput(df)
structure(list(IDs = c(123L, 234L, 568L, 345L), Name = structure(c(1L, 
2L, 4L, 3L), .Label = c("ABC", "CDE", "FGH", "GHJ"), class = "factor"), 
    col1 = structure(c(2L, 3L, 1L, 4L), .Label = c("123456", 
    "1.3,1.3,1.3,1.3,1.3", "2,2,2,2,2", "9,9,9,9,9"), class = "factor"), 
    col2 = structure(1:4, .Label = c("0,0,0,0,0", "0.3,0.3,0.3,0.3,0.3", 
    "123456", "54,54,54,54,54"), class = "factor"), col3 = structure(c(4L, 
    2L, 3L, 1L), .Label = c("0,0,0,0,0", "1,1,1,1,1", "123456", 
    "5,5,5,5,5"), class = "factor")), .Names = c("IDs", "Name", 
"col1", "col2", "col3"), class = "data.frame", row.names = c(NA, 
-4L))

3 个答案:

答案 0 :(得分:4)

首先,我们使用gather()以长格式重新构建数据,然后使用filter() value ,重新构建数据,grepl()使用value。然后,我们使用strsplit()unnest()中的字符串拆分为一个列表,并使用distinct()将列表中的每个元素作为自己的行。我们使用spread()key删除重复行,将valueslibrary(dplyr) library(tidyr) df %>% gather(key, value, -(IDs:Name)) %>% filter(grepl(",", value)) %>% mutate(value = strsplit(value, ",")) %>% unnest(value) %>% distinct %>% spread(key, value) 添加回列。

#Source: local data frame [3 x 5]
#
#    IDs   Name  col1  col2  col3
#  (int) (fctr) (chr) (chr) (chr)
#1   123   AB.C   1.3     0     5
#2   234   CD-E     2   0.3     1
#3   345    FGH     9    54     0

给出了:

cSplit

另一个想法是使用splitstackshape中的df %>% cSplit(., c("col1", "col2", "col3"), direction = "long", sep = ",") %>% group_by(Name) %>% filter(!any(is.na(.))) %>% distinct

#Source: local data table [3 x 5]
#Groups: Name
#
#    IDs   Name  col1  col2  col3
#  (int) (fctr) (dbl) (dbl) (int)
#1   123   AB.C   1.3   0.0     5
#2   234   CD-E   2.0   0.3     1
#3   345    FGH   9.0  54.0     0

给出了:

DELETE FROM patienten WHERE idPatient= :idn

答案 1 :(得分:1)

以下是适用于您的样本数据的基本R方法:

df <- read.table(header=T, text="IDs Name    col1    col2    col3
 123 ABC 1.3,1.3,1.3,1.3,1.3 0,0,0,0,0   5,5,5,5,5
                  234 CDE 2,2,2,2,2   0.3,0.3,0.3,0.3,0.3 1,1,1,1,1
                  568 GHJ 123456      123456              123456
                  345 FGH 9,9,9,9,9   54,54,54,54,54  0,0,0,0,0")

# drop rows with no comma or dot
df <- df[-grep("[,.]", df$col1, invert=T),]

df[,grep("^col", names(df))] <- sapply(df[,grep("^col", names(df))], 
                                       function(i) gsub("^([0-9.]+),.*", "\\1", i))

返回

  IDs Name   col1   col2   col3
1 123  ABC    1.3      0      5
2 234  CDE      2    0.3      1
3 568  GHJ 123456 123456 123456
4 345  FGH      9     54      0

我们使用正则表达式函数grepgsub来选择正确的列并删除逗号后面的每个字符串的部分。

答案 2 :(得分:1)

基础R中的长"object": ...方式:

apply

给出了:

as.data.frame( apply( df, c(1,2), gsub, pattern="(\\d*[.]*\\d*),.*", replacement="\\1") )

这个想法是只保留每个项目的第一个逗号之前的第一个元素

缺点(?)它保持行没有小数值。