【问题标题】:R: Compute a new dataframe column from a function that calls functionsR:从调用函数的函数计算新的数据框列
【发布时间】:2017-10-20 17:21:53
【问题描述】:

我正在尝试使用多参数计算数据框的新列 功能。当该功能很简单时,一切都很好。当那个 函数调用另一个函数,事情出错了。

第 1 部分:感兴趣的数据集。

# The goal is to transform Foo into a new column.
df <- data.frame(
   Year =c(1901,1901,1900,1902),
   Month=c(   2,   1,   2,   1),
   Foo  =c(   1,   2,   3,   4)
)

# This simple multi-arg transform works fine.
Foo2Baz <- function(year, month, foo) {
  return(year + month + foo)
}
df$Baz <- Foo2Baz(df$Year, df$Month, df$Foo)
# Expected Baz column: [1904, 1904, 1905, 1907] 
df$Baz
[1] 1904 1904 1905 1907

第 2 部分:查找表

失败的更有趣的转换就像上面的 Foo2Baz, 除了它会调用另一个函数来查找某个值 其他表。

# First we load a dataframe that backs the lookup operation. It's nice
# to keep as a dataframe, as opposed to matrix, for human inspection
# of cells.
lookup_table <- data.frame(
  Year=c(1900, 1901, 1902),
  Jan =c(  10,   20,   30),
  Feb =c( 100,  200,  200))

# Then we define a function to lookup a cell.
Lookup <- function(year, month) {
  return(lookup_table[
    year - 1899, # converts year to row index
    1 + month    # converts month to column, skipping 'Year'
  ])
}
# We expect a lookup of 1901-Feb to be 200
Lookup(1901, 2)
[1] 200

第 3 部分:调用函数的转换函数。

# The goal is to transform Foo into new column Bar
# by looking up that case's Year and Month.
Foo2Bar <- function(year, month, foo) {
  return(foo + Lookup(year, month))
}

# We expect case 1 (1901,Feb,Foo=1) to have Bar=201
Foo2Bar(1901,2,1)
[1] 201

# We expect case 4 (1902,Jan,Foo=4) to have Bar=34
Foo2Bar(1902,1,4)
[1] 34

第 4 部分:如何计算 Bar 的新列?

似乎我们现在可以使用 Foo2Bar 计算 Bar 列,就像 我们使用了更简单的 Foo2Baz:

df$Bar <- Foo2Bar(df$Year, df$Month, df$Foo)
df$Bar
    Feb Jan Feb.1 Jan.1
2   201  21   201    21
2.1 202  22   202    22
1   103  13   103    13
3   204  34   204    34

没有专栏?取而代之的是一个矩阵,其中行和列看起来像我们发送给 Lookup() 函数的各种输入?!

我尝试了 do.call、apply、lapply、sapply 和 dplyr mutate 的变体。我似乎只是在这里遗漏了一些基本的东西。

【问题讨论】:

  • df$Month 是一个向量,因此您将返回几列 Lookup 和几行,这是预期的
  • 我想你想要 df$Bar
  • 感谢穆迪,我确信 '$' 或 mutate() 以及其他任何应该在计算新列时“为每一行...”做的事情。此外,在您的回答中,它需要在大括号之前有一个右括号,但这会导致错误以“ if (inherits(X[[j]], "data.frame")..." 开头的错误我读到并重读了 apply、lapply 和更多次,但仍然没有理解这些函数真正在做什么,或者真正的论点!
  • 我是用手机输入的,没有经过测试抱歉:)。这有效:
  • df$Bar

标签: r


【解决方案1】:

我们只需要cbind

Lookup <- function(year, month) {
   lookup_table[cbind(
           year - 1899, 
             1 + month)   
     ]
 }

Lookup(1901, 2)
#[1] 200
Foo2Bar(1901,2,1)
#[1] 201

df$Bar <- Foo2Bar(df$Year, df$Month, df$Foo)
df
#  Year Month Foo Bar
#1 1901     2   1 201
#2 1901     1   2  22
#3 1900     2   3 103
#4 1902     1   4  34

【讨论】:

  • 阿克伦,谢谢!您的答案只需要在查找函数中删除右方括号后的右括号!我仍然试图准确地了解这里发生了什么。给定两列 cbind 将返回与它们组合的框架,好的。因此,您的调用从 df$Year 和 Month 的每一行的这些参数的简单表达式中生成两列。然后索引:lookup_table[cbind(...)] 做什么?这里发生了什么不同? :)
  • @dimfish 谢谢,我在删除 return( 后忘记删除右大括号 这是一种行/列索引方法,其中行和列向量为 cbind 创建一个矩阵来提取基于索引的数据集元素
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-02-09
  • 1970-01-01
  • 1970-01-01
  • 2021-12-23
  • 2011-05-09
  • 2023-03-11
  • 1970-01-01
相关资源
最近更新 更多