【问题标题】:How to assign a value to a column based on a column index如何根据列索引为列赋值
【发布时间】:2018-06-01 08:50:09
【问题描述】:

有一个数据框我想根据给定的列索引分配一个计算值

df <- data.frame(a = c(2,4,7,3,5,3), b = c(8,3,8,2,6,1))

> df
   a b
 1 2 8     
 2 4 3
 3 7 8
 4 3 2
 5 5 6
 6 3 1

max <- apply(df, 1, which.max)
> max
[1] 2 1 2 1 2 1

addition <- apply(df, 1, sum)
> addition
[1] 10  7 15  5 11  4

然后一些我无法弄清楚的操作将以下结果分配给 df2

> df2
  a  b
1 2 10
2 7  3
3 7 15
4 5  2
5 5 11
6 4  1

非常感谢您的想法和帮助。谢谢你

【问题讨论】:

    标签: r


    【解决方案1】:

    您可以使用cbind 访问您为每一行选择的列:

    df2 = df
    df2[cbind(1:nrow(df2),max)] = addition
    df2
      a  b
    1 2 10
    2 7  3
    3 7 15
    4 5  2
    5 5 11
    6 4  1
    

    这里,cbind 返回一个 2 列和 6 行的矩阵,我们使用矩阵子集对数据框进行子集化。

    【讨论】:

    • 你可以在没有apply 调用max.colrowSums 的情况下做到这一点:df[cbind(seq(nrow(df)), max.col(df))] &lt;- rowSums(df)
    • 非常感谢!我错过了左侧的cbind()。我正在尝试df[,max] &lt;- addition。能否解释一下为什么这会引发错误,但包括cbindseq 生成的行索引有效?
    • 例如,使用df[,c(2,1,2,1,2,1)] 会选择整个第 2 列、第 1 列、第 2 列、第 1 列等,从而生成具有 6 列和 6 行的数据框。这就是为什么在尝试为其分配加法向量时会出错的原因。这里,cbind() 返回一个matrix,我们用它来子集数据帧。
    【解决方案2】:

    您也可以直接使用矢量化ifelse

    with(df, cbind.data.frame(a = ifelse(a > b, a + b, a), b = ifelse(a > b, b, a + b)));
    #  a  b
    #1 2 10
    #2 7  3
    #3 7 15
    #4 5  2
    #5 5 11
    #6 4  1
    

    【讨论】:

    • 谢谢!这样可行。如果试图避免ifelsestatements,因为有了这些职位,我觉得它更优雅。但尽管如此,这也有效,我认为这对读者来说更清楚。
    • @JeanPaul 不用担心,很高兴为您提供帮助。请记住,ifelse 是矢量化的,因此与cbind 方法进行基准比较以查看哪种方法更快会很有趣。
    猜你喜欢
    • 1970-01-01
    • 2022-08-09
    • 2021-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-17
    • 1970-01-01
    相关资源
    最近更新 更多