【问题标题】:Using for loop to multiply variables and create product variables使用 for 循环乘以变量并创建产品变量
【发布时间】:2021-11-27 01:23:21
【问题描述】:

我需要编写一个for循环来计算年份变量(例如var1874)*价格变量(例如num1874)的乘积,为每年创建一个新变量及其对应的价格值(例如newvar1874)。

A tibble: 4 x 7
    cty var1874 var1875 var1876 num1874 num1875 num1876
  <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
1     1    0.78    0.83    0.99    2.64    2.8     3.1 
2     2    0.69    0.69    0.89    2.3     2.3     2.58
3     3    0.42    0.48    0.59    2.28    2.44    2.64
4     4    0.82    0.94    1.09    2.28    2.36    3   

# Here's the code I have so far...
       
var.num_ <- dim(mydata)[2]
for(i in 1:length(vars)) {
  mydata[, var.num + i] <- recode(mydata[, vars[i]], "newvar")
  names(mydata)[var.num + i] <- paste0("newvar", vars[i])
} 
 
# This code generates new variables, but they all have NA values.
# I also get this error message: 

Unreplaced values treated as NA as .x is not compatible. 
Please specify replacements exhaustively or supply .default  

# Does anyone have any tips or general suggestions on how to use 
# a for loop to multiply variables and create new product variables?

【问题讨论】:

  • 只要做 newvar1874
  • 我将如何使用 for 循环来做到这一点?
  • 在 R 中,星号 (*) 用于逐元素乘法。这是同一行中的元素相乘的地方。

标签: r


【解决方案1】:

你可以简单地做子集然后乘:

df[2:4]*df[5:7]

  var1874 var1875 var1876
1  2.0592  2.3240  3.0690
2  1.5870  1.5870  2.2962
3  0.9576  1.1712  1.5576
4  1.8696  2.2184  3.2700

如果您不知道列数,但数据按给定排列,那么您可以这样做:

df %>%
  transmute(across(starts_with('var')) * across(starts_with('num')))
  var1874 var1875 var1876
1  2.0592  2.3240  3.0690
2  1.5870  1.5870  2.2962
3  0.9576  1.1712  1.5576
4  1.8696  2.2184  3.2700

如果数据杂乱无章怎么办?即您不确定年份的排列方式是num 的排列方式。然后做:

df %>%
  pivot_longer(-cty, names_to = c('.value', 'grp'), 
               names_pattern = '(\\D+)(\\d{4})') %>%
  mutate(newvar = var * num) %>%
  pivot_wider(cty, grp, values_from = newvar, names_prefix = 'newvar')

   cty newvar1874 newvar1875 newvar1876
  <int>      <dbl>      <dbl>      <dbl>
1     1      2.06        2.32       3.07
2     2      1.59        1.59       2.30
3     3      0.958       1.17       1.56
4     4      1.87        2.22       3.27

在基础 R 中,可以这样做:

【讨论】:

    【解决方案2】:

    使用基数 R,我们可以利用向量乘法。

    # Data --------------------------------------------------------------------
    
    df <- data.frame(cty = 1:4,
                    var1874 = c(.78, .69, .42, .82),
                    var1875 = c(.83, .69, .48, .94),
                    var1876 = c(.99, .89, .59, 1.09),
                    num1874 = c(2.64, 2.3, 2.28, 2.28),
                    num1875 = c(2.8, 2.3, 2.44, 2.36),
                    num1876 = c(3.1, 2.58, 2.64, 3))
    
    
    # code --------------------------------------------------------------------
    
    nms_var <- paste0(c('var187'), 4:6)
    nms_num <- gsub('var', 'num', nms_var)
    nms_result <- gsub('var', 'new_var', nms_var)
    
    for (i in 1:length(nms_var)) {
      df[, nms_result[[i]]] <- df[, nms_var[i]] * df[, nms_num[i]]
    }
    
    df
    #>   cty var1874 var1875 var1876 num1874 num1875 num1876 new_var1874 new_var1875
    #> 1   1    0.78    0.83    0.99    2.64    2.80    3.10      2.0592      2.3240
    #> 2   2    0.69    0.69    0.89    2.30    2.30    2.58      1.5870      1.5870
    #> 3   3    0.42    0.48    0.59    2.28    2.44    2.64      0.9576      1.1712
    #> 4   4    0.82    0.94    1.09    2.28    2.36    3.00      1.8696      2.2184
    #>   new_var1876
    #> 1      3.0690
    #> 2      2.2962
    #> 3      1.5576
    #> 4      3.2700
    

    reprex package (v2.0.1) 于 2021 年 11 月 27 日创建

    【讨论】:

      猜你喜欢
      • 2021-12-09
      • 2015-12-26
      • 2018-02-18
      • 2012-01-21
      • 1970-01-01
      • 2018-02-10
      • 1970-01-01
      • 1970-01-01
      • 2014-05-20
      相关资源
      最近更新 更多