【问题标题】:Divide only one column of nested data.frames by an integer value仅将一列嵌套 data.frames 除以整数值
【发布时间】:2014-06-03 08:23:47
【问题描述】:

我希望将数据框的第三列除以 5。这些数据框是嵌套的,如下所示:

[[44]]
    Ethnicity      Variant  Sum
 1:       ASW     ACCEPTOR    1
 2:       ASW          CDS   68
 3:       ASW   CGA_CNVWIN 1000
 4:       ASW     CGA_MIRB    0
 5:       ASW       DELETE    0
 6:       ASW      DISRUPT    0
 7:       ASW        DONOR    0
 8:       ASW   FRAMESHIFT    0
 9:       ASW       INSERT    1
10:       ASW       INTRON   54

我使用了三个命令,每个命令都成功但有脱靶效果。

lapply(ASWldtSUM,function(x)(x/5))

返回

[[44]]
    Ethnicity Variant   Sum
 1:        NA      NA   0.2
 2:        NA      NA  13.6
 3:        NA      NA 200.0
 4:        NA      NA   0.0
 5:        NA      NA   0.0

这具有将所有行除以 5 的不幸效果,当类不是 $Sum 列中的整数时会导致问题。

lapply(ASWldtSUM,function(x[,3])(x/5))

具有只返回单个向量的效果,如果这不是数据帧的嵌套数组,而是语句,这将很好地工作

ASWdtSUM$NEWCOL<-lapply(ASWldtSUM,function(x[,3])(x/5))

不能简单地写,因为它是嵌套的。

在以下语句中使用 rapply:

rapply(ASWldtSUM,function(x) if (is.integer(x)) {(x/5)})

导致结果混乱。

那么,有没有一种简单的方法可以将第 4 列附加到每个嵌套的 DataFrame,或者将每个 DF(Sum)的第三列替换为除以 5 的值?

【问题讨论】:

  • lapply(yourdflist, function(x) x$Sum/5)
  • @PauloCardoso 您的建议仅返回除以五的第三列,而不是所有整个数据帧。
  • 是的。这就是我不回答的原因。并且该函数不是匿名的。只是一种简单的方法来演示该原理。用户在下面得到了一个很好的答案。
  • 嗨,在标记之前花点时间阅读标记摘录。 dataframes 用于熊猫,而您需要 data.frame 在这里。下次小心点。请参阅此元帖子。 Warn [r] users from adding [dataframes] tag instead of [data.frame] tag

标签: r dataframe nested lapply


【解决方案1】:

很简单,如果ASWldtSUM是包含数据框的列表的名称,那么你可以这样做:

lapply(ASWldtSUM,FUN=function(x) { x[,3]=x[,3]/5; return(x) })

基本上,您将(整个)第三列替换为(整个)第三列除以五。

在实践中:

> ASWldtSUM1=data.frame(Ethnicity=rep('ASW',10),Variant=c("ACCEPTOR","CDS","CGA_CNVWIN","CGA_MIRB","DELETE","DISRUPT","DONOR","FRAMESHIFT","INSERT","INTRON"), Sum=c(1,68,1000,0,0,0,0,0,1,54))
> #created a first data.frame (equal to your example)
> ASWldtSUM2=data.frame(Ethnicity=rep('ASW',10),Variant=c("ACCEPTOR","CDS","CGA_CNVWIN","CGA_MIRB","DELETE","DISRUPT","DONOR","FRAMESHIFT","INSERT","INTRON"), Sum=c(1,2,3,4,5,6,7,8,9,10))
> #created a second data.frame (with different values for the third column)
> ASWldtSUM=list(ASWldtSUM1,ASWldtSUM2)
> #created a list of data frames
> lapply(ASWldtSUM,FUN=function(x) { x[,3]=x[,3]/5; return(x) })
> #apply the function to divide third column to each nested data.frame
[[1]]
   Ethnicity    Variant   Sum
1        ASW   ACCEPTOR   0.2
2        ASW        CDS  13.6
3        ASW CGA_CNVWIN 200.0
4        ASW   CGA_MIRB   0.0
5        ASW     DELETE   0.0
6        ASW    DISRUPT   0.0
7        ASW      DONOR   0.0
8        ASW FRAMESHIFT   0.0
9        ASW     INSERT   0.2
10       ASW     INTRON  10.8

[[2]]
   Ethnicity    Variant Sum
1        ASW   ACCEPTOR 0.2
2        ASW        CDS 0.4
3        ASW CGA_CNVWIN 0.6
4        ASW   CGA_MIRB 0.8
5        ASW     DELETE 1.0
6        ASW    DISRUPT 1.2
7        ASW      DONOR 1.4
8        ASW FRAMESHIFT 1.6
9        ASW     INSERT 1.8
10       ASW     INTRON 2.0
> #desired result

【讨论】:

  • 这将返回“ASWldtSUM[, 3] 中的错误:维数不正确”
  • @VincentLaufer 绝对不是,这是一个矢量运算,在 R 中是完全合法的,请参阅我在答案中添加的示例
  • 嗨@EnneCH - 非常感谢您的回答,但我认为您可能错过了这些是嵌套在数组中的数据帧这一事实。即 ASWldtSUM$Sum 将返回“NULL” ASWldtSUM[[1]]$Sum 将返回值
  • @VincentLaufer 好的,所以我调整了我的答案,方法仍然相同,仅适用于列表,不再适用于单个 data.frame
  • 非常感谢您的帮助和坚持。我根据您的回答“lapply(ASWldtSUM,FUN=function(x) { x$Sum
【解决方案2】:

有很多方法可以做到这一点。这是一个:

创建一些示例数据:

dat <- lapply(1:3, function(x)data.frame(a=sample(letters, 4), b=sample(LETTERS, 4), z=rnorm(4)))

dat
[[1]]
  a b          z
1 r M  0.3054329
2 v I -0.8051859
3 t Q -1.6082701
4 u D -0.2315290

[[2]]
  a b          z
1 j W -0.4692469
2 f S  0.3112689
3 a D  0.4208704
4 w Z  0.6903139

[[3]]
....

接下来,在lapply() 中使用一个小的匿名函数。为了更好地说明,我乘以 100 而不是除以 5:

lapply(dat, function(x){x[3] <- x[3]*100; x})

[[1]]
  a b          z
1 r M   30.54329
2 v I  -80.51859
3 t Q -160.82701
4 u D  -23.15290

[[2]]
  a b         z
1 j W -46.92469
2 f S  31.12689
3 a D  42.08704
4 w Z  69.03139

[[3]]
....

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 2019-05-05
    • 2017-02-26
    • 1970-01-01
    相关资源
    最近更新 更多