【问题标题】:r subset and subtract one column from other columns in a data.framer 子集并从 data.frame 中的其他列中减去一列
【发布时间】:2017-11-10 23:49:57
【问题描述】:

我想知道是否有人可以帮助我编写一个函数来执行此操作。我有一个如下所示的数据框:

df <- data.frame(TestA1 = c(1,2), TestA2 = c(2,3), TestB1 = c(3,4), TestB2 = c(5,6), A = c(1,1), B = c(2,2))
df
TestA1 TestA2 TestB1 TestB2 A B
1      2      3      5 1 2
2      3      4      6 1 2

我想从名称中包含 A 的所有其他列(即 TestA1 和 TestA2)中减去“A”列,并对 B 及其匹配列执行相同操作。在一个功能中尝试和做这件事太多了吗?

我还是 R 新手,我一直在我的数据集上逐个进行此操作,它似乎非常低效(完整数据集为 25000x55)。我一直在努力思考如何编写一个函数来做到这一点,并且一直在苦苦挣扎。任何帮助/指导将不胜感激!

编辑

理想的输出是(如果选择 B)

NewTestB1  NewTestB2
1          3
2          4

因此,B = c(2,2) 将从匹配的每一列中减去,从而生成一个输出数据帧,其中包含已选择的列和额外的调整。

【问题讨论】:

  • 一列是否可以同时是 A 和 B?你是说你事先不知道列名,必须搜索匹配项?
  • 不,列不可能同时存在。我事先知道列名我只是希望能够编写它,以便我可以匹配需要从其他列中减去的列作为匹配名称的组成部分,而不需要分成几个较小的数据框
  • 使用 names() 获取名称,然后 grepl() 为 A 和 B 获取名称。然后做减法 Avars - A .
  • 根据上述:library(dplyr) df %>% select(grep("A", names(df)))

标签: r function


【解决方案1】:

在base R中,提供你想要的功能:

myF <- function( object, selector )
{
    ix <- which( grepl( selector, colnames( object ) ) & colnames( object ) != selector )
    rowSums( object[ ix ] ) - object[ selector ]
}

所以打电话

myF( df, "B" ) 

会给你

  B
1 6
2 8

这是基于您肯定简化的示例,可能需要进行一些调整。您可能还想重命名返回的 data.frame,但这一切都取决于您对结果的进一步使用。

如果您想返回一个向量,而不是一列 data.frame,请更改为

rowSums( object[ ix ] ) - object[ selector ][ , 1 ]

编辑:

这可能就是你想要的:

myF <- function( object, selector )
{
    ix <- which( grepl( selector, colnames( object ) ) & colnames( object ) != selector )
    for( i in ix )
        object[ length( object ) + 1 ] <- object[ i ] - object[ selector ]
    return( object )
}

这给了你

myF( df, "B" )
  TestA1 TestA2 TestB1 TestB2 A B TestB1.1 TestB2.1
1      1      2      3      5 1 2        1        3
2      2      3      4      6 1 2        2        4

可能会进行一些改进,例如更好的列名等,但功能已实现。另外,请注意,这不会更改原始 data.frame,但会为您提供更新的副本。

第二次编辑,删除列:

myF <- function( object, selector )
{
    ix <- which( grepl( selector, colnames( object ) ) & colnames( object ) != selector )
    for( i in ix )
        object[ length( object ) + 1 ] <- object[ i ] - object[ selector ]
    object <- object[ -ix ]
    object <- object[ -(which( colnames( object ) == selector ) ) ]
    return( object )
}

生产

myF( df, "B" )
  TestA1 TestA2 A TestB1.1 TestB2.1
1      1      2 1        1        3
2      2      3 1        2        4

【讨论】:

  • 感谢代码!我试图对其进行一些调整,因为我实际上需要每个 TestB 列分别从中减去 B,并且输出将是所有新的/调整后的 TestB 的 data.frame。我取出 rowSums 使其只是 object[ix] - object[selector] 但我得到的错误是“-”仅适用于相同大小的数据帧。我将如何编写它以便将减法应用于每一列?
  • 您的意思是从 TestB1 中减去 B,创建具有该值的列,然后从 TestB2 中减去 B,创建具有该值的另一​​列?
  • 是的,所以输出将是一个 2x2 数据帧,其中 TestB1 和 TestB2 的新值已从其中减去 B(无法弄清楚如何在 cmets 中举例说明,但我将其添加到原始帖子中)
  • 我认为这将是一个 for 循环会有所帮助的情况......即对于 object[ix] - object[selector] 中的每一列......但仍然会遇到问题for 循环,所以不完全确定
  • 好的,谢谢!这更像是我正在寻找的东西。我能问一下“object[length(object) + 1]”部分到底在做什么吗?以及返回的输出是否有可能不包括原始列?
猜你喜欢
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-07
相关资源
最近更新 更多