【问题标题】:Is it possible to create a new column in a dataframe that is the output of a function using mutate in R?是否可以在数据框中创建一个新列,该列是在 R 中使用 mutate 的函数的输出?
【发布时间】:2021-11-14 14:09:15
【问题描述】:

我需要跨行运行一个自制函数,并在同一个数据框中创建一个输出列(列名tt_daily)。这是一些虚构的例子。

#data
data1 <- read.csv(text = "
doy,tmx,tmn,relHum,srad
148,31.3,13.8,68.3,30.4
149,31.1,17.2,62.2,30
150,30.1,16.1,69.7,20.9
151,27.3,16.2,77.1,26.1
152,33.4,18.4,65.9,27.4
153,27.2,18,70.3,26.6
154,30.3,13,71.5,28.4
155,36.2,22,62.2,28.8
156,32.9,22.2,61.1,24.9
157,30.5,16.2,63.2,27.9
158,25.7,19.3,71,18.3
159,29.1,18.3,87.2,12.7
160,28.5,20.3,70.2,24.8
")

这是函数:

# function to run row wise
tb<- 11
topt<- 30
tmax<- 42

tt<-function(tmx, tmn, tb, topt, tmax){
  
  tmean<- (tmx + tmn) / 2
  
  if(tmean <= tb) {t1 = 0}
  if(tmean >tb & tmean <=topt) {t1 = tmean - tb}
  if(tmean>topt & tmean<max) {t1 = (topt - tb) / (topt - tmax) * (tmean - tmax)}
  if(tmean >= tmax) {t1 <- 0}
  return(t1)
  
}

这是我所做的两个选择:

#Option 1
library(dplyr)

tt.example <- data1 %>%
  mutate(tt_daily = purrr::pmap(function(tmx, tmn, tb, topt, tmax) tt))

这是错误:

错误:mutate()tt_daily 有问题。 我tt_daily = purrr::pmap(function(tmx, tmn, tb, topt, tmax) tt)。 x 参数“.f”丢失,没有默认值

这是选项2:

#Option 2
tt.example <- data1 %>%
  rowwise() %>%
  mutate(tt_daily = tt(tmx, tmn, tb, topt, tmax))

这是我得到的错误:

错误:mutate()tt_daily 有问题。 我tt_daily = tt(tmx, tmn, tb, topt, tmax)。 x 比较 (3) 仅适用于 atomic 和 list 类型 i 错误发生在第 1 行。

感谢您的建议。

【问题讨论】:

  • @akrun,不,它们被设置为数据集之外的对象。这是错的吗?

标签: r dplyr purrr


【解决方案1】:

函数中有错字,应该是tmax 而不是max

tt<-function(tmx, tmn, tb, topt, tmax){
  
  tmean<- (tmx + tmn) / 2
  
  
  if(tmean <= tb) {t1 = 0}
  if(tmean >tb & tmean <=topt) {t1 = tmean - tb}
  if(tmean>topt & tmean<tmax) {t1 = (topt - tb) / (topt - tmax) * (tmean - tmax)}
  if(tmean >= tmax) {t1 <- 0}
  return(t1)
  
}

现在,我们在 pmap 内附加其他参数作为命名 list 后,在 mutate 内应用该函数

library(dplyr)
library(purrr)
data1 %>% 
    mutate(tt_daily = pmap_dbl(c(across(tmx:tmn), 
             dplyr::lst(tb, topt, tmax)), tt))

-输出

doy  tmx  tmn relHum srad tt_daily
1  148 31.3 13.8   68.3 30.4    11.55
2  149 31.1 17.2   62.2 30.0    13.15
3  150 30.1 16.1   69.7 20.9    12.10
4  151 27.3 16.2   77.1 26.1    10.75
5  152 33.4 18.4   65.9 27.4    14.90
6  153 27.2 18.0   70.3 26.6    11.60
7  154 30.3 13.0   71.5 28.4    10.65
8  155 36.2 22.0   62.2 28.8    18.10
9  156 32.9 22.2   61.1 24.9    16.55
10 157 30.5 16.2   63.2 27.9    12.35
11 158 25.7 19.3   71.0 18.3    11.50
12 159 29.1 18.3   87.2 12.7    12.70
13 160 28.5 20.3   70.2 24.8    13.40

或使用rowwise

data1 %>% 
   rowwise %>% 
   mutate(tt_daily = tt(tmx, tmn, tb, topt, tmax)) %>%
   ungroup

-输出

# A tibble: 13 x 6
     doy   tmx   tmn relHum  srad tt_daily
   <int> <dbl> <dbl>  <dbl> <dbl>    <dbl>
 1   148  31.3  13.8   68.3  30.4     11.6
 2   149  31.1  17.2   62.2  30       13.2
 3   150  30.1  16.1   69.7  20.9     12.1
 4   151  27.3  16.2   77.1  26.1     10.8
 5   152  33.4  18.4   65.9  27.4     14.9
 6   153  27.2  18     70.3  26.6     11.6
 7   154  30.3  13     71.5  28.4     10.6
 8   155  36.2  22     62.2  28.8     18.1
 9   156  32.9  22.2   61.1  24.9     16.5
10   157  30.5  16.2   63.2  27.9     12.4
11   158  25.7  19.3   71    18.3     11.5
12   159  29.1  18.3   87.2  12.7     12.7
13   160  28.5  20.3   70.2  24.8     13.4

如果我们想添加一个新列,那么在 'tt' 函数中返回 listtibble 可能会更好

tt<-function(tmx, tmn, tb, topt, tmax){
   
   tmean<- (tmx + tmn) / 2
   
   
   if(tmean <= tb) {t1 = 0}
   if(tmean >tb & tmean <=topt) {t1 = tmean - tb}
   if(tmean>topt & tmean<tmax) {t1 = (topt - tb) / (topt - tmax) * (tmean - tmax)}
   if(tmean >= tmax) {t1 <- 0}
   return(tibble(tt_daily = t1, tmean = tmean))
   
 }

现在,我们将内容包装在 listunnest 输出列中

library(tidyr)
data1 %>% 
    rowwise %>% 
    mutate(out = list(tt(tmx, tmn, tb, topt, tmax))) %>%
    ungroup %>% 
    unnest_wider(c(out))
# A tibble: 13 x 7
     doy   tmx   tmn relHum  srad tt_daily tmean
   <int> <dbl> <dbl>  <dbl> <dbl>    <dbl> <dbl>
 1   148  31.3  13.8   68.3  30.4     11.6  22.6
 2   149  31.1  17.2   62.2  30       13.2  24.2
 3   150  30.1  16.1   69.7  20.9     12.1  23.1
 4   151  27.3  16.2   77.1  26.1     10.8  21.8
 5   152  33.4  18.4   65.9  27.4     14.9  25.9
 6   153  27.2  18     70.3  26.6     11.6  22.6
 7   154  30.3  13     71.5  28.4     10.6  21.6
 8   155  36.2  22     62.2  28.8     18.1  29.1
 9   156  32.9  22.2   61.1  24.9     16.5  27.6
10   157  30.5  16.2   63.2  27.9     12.4  23.4
11   158  25.7  19.3   71    18.3     11.5  22.5
12   159  29.1  18.3   87.2  12.7     12.7  23.7
13   160  28.5  20.3   70.2  24.8     13.4  24.4

【讨论】:

  • 有什么方法可以使用rowwise 近似值添加具有tmean 值的列?从我读到的,这些函数只提供一个输出。但我想知道是否有办法以某种方式添加带有该中间对象的列。感谢您的任何提示。
  • @GiuseppePetri 我认为您可以在函数中返回tibble 请检查更新的解决方案
  • 这太棒了。效果很好。
猜你喜欢
  • 2020-09-08
  • 2016-10-25
  • 1970-01-01
  • 2012-01-14
  • 2011-08-09
  • 1970-01-01
  • 2018-05-27
  • 1970-01-01
  • 2023-01-29
相关资源
最近更新 更多