首页 文章

R:从调用函数的函数计算新的数据帧列

提问于
浏览
1

我正在尝试使用多参数函数为数据帧计算新列 . 当这个功能很简单时,一切都很好 . 当该函数调用另一个函数时,事情就会出错 .

第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

PART 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 . 我似乎只是缺少一些基本的东西 .

1 回答

  • 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
    

相关问题