【问题标题】:Apply function to rows return vector instead of list将函数应用于行返回向量而不是列表
【发布时间】:2017-05-07 03:50:51
【问题描述】:

我有一个数据框(以下是简化版)

b<-data.frame('v1'=1:2,'v2'=3:4,'v3'=5:6)

如果我对行使用应用:

test<-apply(b,1,function(x) {if (x[length(x)]>0) return (x/x[length(x)]) else return (0)})

我明白了:

[,1]      [,2]
v1  0.2 0.3333333
v2  0.6 0.6666667
v3  1.0 1.0000000

到目前为止一切顺利,因为我确实需要列名 v1、v2、v3 成为测试中的行名。 但是如果数据框全为零,

b1<-data.frame('v1'=c(0,0),'v2'=c(0,0),'v3'=c(0,0))
test<-apply(b1,1,function(x) {if (x[length(x)]>0) return (x/x[length(x)]) else return (0)})

test 将返回一个向量 0 0 我的问题是如何让测试返回类似

[,1]      [,2]
v1  0      0
v2  0      0
v3  0      0

基本上,如果一行中的最后一个为零,我希望将行中的所有内容都设为 0,更重要的是,我希望返回一个列表,以便获得 v1、v2、v3 行名称(我可以更改为数据框如果返回是列表),现在返回向量 0,0 我丢失了 v1、v2、v3 的所有信息。为什么全零会产生如此大的差异?

【问题讨论】:

    标签: r apply


    【解决方案1】:

    为什么不创建一个函数,将数据帧除以最后一列,然后用零替换 NA?

    prop_last_col <- function(df) {
            prop <- df / df[, ncol(df)]
            prop[is.na(prop)] <- 0
            return(prop)
        }
    
    prop_last(b)
             v1        v2 v3
    1 0.2000000 0.6000000  1
    2 0.3333333 0.6666667  1
    
    
     prop_last(b1)
      v1 v2 v3
    1  0  0  0
    2  0  0  0
    

    如果您希望它的格式与您的示例相同,您可以转置结果。

    【讨论】:

    • 感谢您的回复。那肯定会奏效。我只是想知道为什么当最后一列全为零而至少一列不为零时,R 的处理方式不同。我希望有人能告诉我解决这个问题的根本原因和直接方法,这样我就不必采取额外的步骤将 NA 转换为零。顺便说一句,如果我可以接受,我可以接受多个解决方案。
    • 那是因为当行的最后一个元素为零时,您将返回一个长度为 1 的数字向量,其值为 0。如果值大于 0,则返回对行的操作(保留名称)。如果您将最后一个返回更改为x * 0,就像在test&lt;-apply(b1,1,function(x) {if (x[length(x)]&gt;0) return (x/x[length(x)]) else return (x * 0)}) 中一样,您将得到您想要的结果。但是我认为这样的代码有点难以阅读。
    • 哦,你只能接受one answer
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多