【问题标题】:aggregate data in columns with duplicate id in R在 R 中聚合具有重复 id 的列中的数据
【发布时间】:2014-03-22 15:00:51
【问题描述】:


我有一个这样的 df:

> dat
    gen M1  M1  M1  M1  M2  M2  M2
    G1  150     142 130 105 96  
    G2  150 145 142 130     96  89
    G3  150 145     130 105 96  
    G4      145 142 130 105     89
    G5  150     142 130 105 96  
    G6      145 142 130     96  89
    G7  150     142     105 96  
    G8  150 145     130 105     89
    G9  150 145 142         96  89

在这里,数据存在于重复的 id 中。我喜欢这样总结:

>dat1
gen M1  M1  M1  M1  agg M2  M2  M2  agg
G1  150     142 130 150/142/130 105 96      105/96
G2  150 145 142 130 150/145/142/130     96  89  96/89
G3  150 145     130 150/145/130 105 96      105/96
G4      145 142 130 145/142/430 105     89  105/89
G5  150     142 130 150/142/130 105 96      105/96
G6      145 142 130 145/142/130     96  89  96/89
G7  150     142     150/142 105 96      105/96
G8  150 145     130 150/145/130 105     89  105/89
G9  150 145 142     150/145/142     96  89  96/89

在这里,在 agg 列中,我根据重复的第一行聚合了所有值。
我喜欢在重复列的末尾创建新列并聚合它。
如何在R中做到这一点。我很困惑

EDIT:
dput(dat)
    structure(list(V1 = structure(c(10L, 1L, 2L, 3L, 4L, 5L, 6L, 
    7L, 8L, 9L), .Label = c("G1", "G2", "G3", "G4", "G5", "G6", "G7", 
    "G8", "G9", "gen"), class = "factor"), V2 = structure(c(2L, 1L, 
    1L, 1L, NA, 1L, NA, 1L, 1L, 1L), .Label = c("150", "M1"), class = "factor"), 
        V3 = structure(c(2L, NA, 1L, 1L, 1L, NA, 1L, NA, 1L, 1L), .Label = c("145", 
        "M1"), class = "factor"), V4 = structure(c(2L, 1L, 1L, NA, 
        1L, 1L, 1L, 1L, NA, 1L), .Label = c("142", "M1"), class = "factor"), 
        V5 = structure(c(2L, 1L, 1L, 1L, 1L, 1L, 1L, NA, 1L, NA), .Label = c("130", 
        "M1"), class = "factor"), V6 = structure(c(2L, 1L, NA, 1L, 
        1L, 1L, NA, 1L, 1L, NA), .Label = c("105", "M2"), class = "factor"), 
        V7 = structure(c(2L, 1L, 1L, 1L, NA, 1L, 1L, 1L, NA, 1L), .Label = c("96", 
        "M2"), class = "factor"), V8 = structure(c(2L, NA, 1L, NA, 
        1L, NA, 1L, NA, 1L, 1L), .Label = c("89", "M2"), class = "factor")), .Names = c("V1", 
    "V2", "V3", "V4", "V5", "V6", "V7", "V8"), class = "data.frame", row.names = c(NA, 
    -10L))

【问题讨论】:

  • 你的dput(...) 很奇怪。它将标题放在第一行,列名称为V1, V2,...。这不是您所质疑的dat 的结构。
  • 我不知道你的数据是怎么变成这样的,但这可能不是故意的。我可以想象这个设置可能会无意中出错。我会先解决这个问题,然后下面的答案之一将起作用。如果您无法自行修复数据,请添加有关如何导入数据的内容,我们会尝试为您修复。
  • 谢谢你们。抱歉,这里我使用了一个简单的示例来展示我的 df 的外观。此外,我只是在没有标题的情况下导入,那就是它会自动为每一列分配标题。正如你所说,你的两个答案都很好!我很清楚!我的实际问题是,是否可以在不手动分配 col id 的情况下识别重复的列标题(如 M1 和聚合)?将其放入 for 循环中,我很困惑如何在循环中前进到下一个 agg?或者申请作品,怎么办?我想如果 v 能够算不上。 M1/M2/M3,然后for循环工作。让我知道你的看法?

标签: r duplicates aggregate


【解决方案1】:

如果缺失值为空白,则此方法有效:

dat$agg1 <- apply(dat[,2:5],1,function(x)paste(x[nchar(x)>0],collapse="/"))
dat$agg2 <- apply(dat[,6:8],1,function(x)paste(x[nchar(x)>0],collapse="/"))

dat <- dat[,c(1:5,9,6:8,10)]
dat
#   gen  M1 M1.1 M1.2 M1.3            agg1  M2 M2.1 M2.2   agg2
# 1  G1 150       142  130     150/142/130 105   96      105/96
# 2  G2 150  145  142  130 150/145/142/130       96   89  96/89
# 3  G3 150  145       130     150/145/130 105   96      105/96
# 4  G4      145  142  130     145/142/130 105        89 105/89
# ...

如果缺失值为NA,则此方法有效

dat$agg1 <- apply(dat[,2:5],1,function(x)paste(x[!is.na(x)],collapse="/"))
dat$agg2 <- apply(dat[,6:8],1,function(x)paste(x[!is.na(x)],collapse="/"))

【讨论】:

    【解决方案2】:

    使用 paste() 将它们聚合成一个字符向量

     x=data.frame(x1=1:10,x2=1:10,x1=11:20)
    
     #now notice that r created my x object with three columns x1,x2 and x1.1
    
     xnew=cbind(x,agg=paste(x$x1,x$x2,x$x1.1,sep="/"))
    

    我不确定这是否是您想要做的,因为我对您的数据结构有点困惑。

    【讨论】:

    • 谢谢赛斯。在我的 df 中,我在 4 列中有 M1,在 3 列中有 M2。在所有列中,我都有值或 NA/空白。我喜欢在每组重复行之后插入新的 col 并像第二个 df 一样聚合它。
    • 你能在你的问题和print(dat)的输出中做一个dput(dat)吗?
    • 如果您将数据放入适当的数据框中,请使用此答案或 jlhoward
    【解决方案3】:

    这是我的脚本...我知道你们中的一些人可以让它变得简单而优雅!
    我转置了我的 df(一个简单的示例)并读取为表格。

     > dat<-read.table("dat.txt", header=T, sep="\t", na.strings="")
        > dat
           gen  A  B  C  D
        1   M1  1 NA  3 NA
        2   M1 NA  6 NA  3
        3   M1  4  8 NA NA
        4   M1 NA NA  6  3
        5   M2  8 NA  6 NA
        6   M2 NA  2 NA  6
        7   M3  3  8 NA  2
        8   M3  8  9  5 NA
        9   M4  3  7  8  5
        10  M4  5 NA  3  2
        > final<-NULL
        > for(i in 1:4){
        +   mar<-as.character(dat[1,1])
        +   dat1<-dat[dat[,1]%in% c(mar),]
        +   dat <- dat[!dat[,1]%in% c(mar),]
        +   dat2 <- apply(dat1,2,function(x)paste(x[!is.na(x)],collapse="/"))
        +   dat2$gen<-mar
        +   dat3<-rbind(dat1,dat2)
        +   final<-rbind(final, dat3)
        + }
        Warning messages:
        1: In dat2$gen <- mar : Coercing LHS to a list
        2: In dat2$gen <- mar : Coercing LHS to a list
        3: In dat2$gen <- mar : Coercing LHS to a list
        4: In dat2$gen <- mar : Coercing LHS to a list
        > final
           gen     A     B     C     D
        1   M1     1  <NA>     3  <NA>
        2   M1  <NA>     6  <NA>     3
        3   M1     4     8  <NA>  <NA>
        4   M1  <NA>  <NA>     6     3
        5   M1  1/ 4  6/ 8  3/ 6  3/ 3
        51  M2     8  <NA>     6  <NA>
        6   M2  <NA>     2  <NA>     6
        31  M2     8     2     6     6
        7   M3     3     8  <NA>     2
        8   M3     8     9     5  <NA>
        32  M3   3/8   8/9     5     2
        9   M4     3     7     8     5
        10  M4     5  <NA>     3     2
        33  M4   3/5     7   8/3   5/2
    

    【讨论】:

      猜你喜欢
      • 2017-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-21
      • 1970-01-01
      • 1970-01-01
      • 2017-01-26
      相关资源
      最近更新 更多