繁体   English   中英

如何将函数应用于多列以在 R 中创建多个新列?

[英]How to apply a function to multiple columns to create multiple new columns in R?

我有这个序列列表aqi_range和一个数据帧df

aqi_range = list(0:50,51:100,101:250)

df

   PM10_mean PM10_min PM10_max PM2.5_mean PM2.5_min PM2.5_max
 1      85.6        3      264       75.7         3       240
 2     105.         6      243       76.4         3       191
 3      95.8       19      287       48.4         8       134
 4      85.5       50      166       64.8        32       103
 5      55.9       24      117       46.7        19        77
 6      37.5        6      116       31.3         3        87
 7      26          5       69       15.5         3        49
 8      82.3       34      169       49.6        25       120
 9      170        68      272       133         67       201
10      254       189      323       226        173       269

现在我已经创建了这两个非常简单的函数,我想将它们应用到这个数据框来计算每种污染物的AQI=空气质量指数

#a = column from a dataframe  **PM10_mean, PM2.5_mean**
#b = list of sequences defined above
min_max_diff <- function(a,b){
        for (i in b){
          if (a %in% i){
           min_val = min(i)
           max_val = max(i)
           return (max_val - min_val)
        }}}

#a = column from a dataframe  **PM10_mean, PM2.5_mean**
#b = list of sequences defined above
c_low <- function(a,b){
      for (i in b){
       if (a %in% i){
        min_val = min(i)
        return(min_val)
          } 
      }}

基本上,第一个函数“min_max_diff”获取列 df$PM10_mean / df$PM2.5_mean 的值并在列表“aqi_range”中检查它,然后返回一个特定值(它所在序列的最小值和最大值的差异)可用的)。 类似地,第二个函数“c_low”只返回序列的最小值。

我想将这种操作(下面定义的公式)应用于 PM10_mean 列以创建新列 PM10_AQI:

df$PM10_AQI  = min_max_diff(df$PM10_mean,aqi_range) / (df$PM10_max - df$PM10_min) / * (df$PM10_mean -  df$PM10_min) + c_low(df$PM10_mean,aqi_range)

我希望它能正确解释。

如果您的问题只是如何计算数据帧中几列的给定转换,您可以编写一个 for 循环,使用字符串转换函数构造转换中涉及的每个变量的名称(在这种情况下sub()很有用) ,并使用[表示法(与$表示法相反——因为[表示法接受字符串来指定列)引用数据框中的列。

下面我展示了一个带有 3 个观察值的小样本数据的代码示例:

(请注意,我修改了 AQI 范围值的定义(现在我只是定义了范围变化的中断点——假设它们都是整数),并且你的函数min_max_diff()c_low()被折叠成一个返回找到值的 AQI 范围的最小值和最大值 - 再次假设 AQI 值是整数值)

# Definition of the AQI ranges (which are assumed to be based on integer values)
# Note that if the number of AQI ranges is k, the number of breaks is k+1
# Each break value defines the minimum of the range
# The maximum of each range is computed as the "minimum of the NEXT range" - 1
# (again this assumes integer values in AQI ranges)
# The values (e.g. PM10_mean) whose AQI range is searched for are assumed
# to NOT be larger than or equal to the largest break value.
aqi_range_breaks = c(0, 51, 101, 251)

# Example data (top 3 rows of the data frame you provided)
df = data.frame(PM10_mean=c(85.6, 105.0, 95.8),
                PM10_min=c(3, 6, 19),
                PM10_max=c(264, 243, 287),
                PM2.5_mean=c(75.7, 76.4, 48.4),
                PM2.5_min=c(3, 3, 8),
                PM2.5_max=c(240, 191, 134))

# Function that returns the minimum and maximum AQI values
# of the AQI range where the given values are found
# `values`: array of values that are searched for in the AQI ranges
# defined by the second parameter.
# `aqi_range_breaks`: breaks defining the minimum values of each AQI range
# plus one last value defining a value never attained by `values`.
# (all values in this parameter defining the AQI ranges are assumed integer values)
find_aqi_range_min_max <- function(values, aqi_range_breaks){
  aqi_range_groups = findInterval(values, aqi_range_breaks)
  return( list(min=aqi_range_breaks[aqi_range_groups],
               max=aqi_range_breaks[aqi_range_groups + 1] - 1))
}

# Run the variable transformation on the selected `_mean` columns
vars_mean = c("PM10_mean", "PM2.5_mean")
for (vmean in vars_mean) {
  vmin = sub("_mean$", "_min", vmean)
  vmax = sub("_mean$", "_max", vmean)
  vaqi = sub("_mean$", "_AQI", vmean)
  aqi_range_min_max = find_aqi_range_min_max(df[,vmean], aqi_range_breaks)
  df[,vaqi] = (aqi_range_min_max$max - aqi_range_min_max$min) / 
              (df[,vmax] - df[,vmin]) / (df[,vmean] -  df[,vmin]) +
              aqi_range_min_max$min
}

请注意findInterval()函数如何用于查找值数组所在的范围。 这是使您的转换适用于数据框列的关键。

此过程的预期输出是:

  PM10_mean PM10_min PM10_max PM2.5_mean PM2.5_min PM2.5_max  PM10_AQI    PM2.5_AQI
1      85.6        3      264       75.7         3       240  51.00227 51.002843893
2     105.0        6      243       76.4         3       191 101.00635 51.003550930
3      95.8       19      287       48.4         8       134  51.00238  0.009822411

请检查计算 AQI 的公式,因为其中存在语法错误(查找/ * ,我已在代码的公式中将其替换为/ )。

请注意,在sub()使用的正则表达式中使用$来匹配字符串"_mean"仅当"_mean"字符串出现在变量名称的末尾时才使用它来替换字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM