【问题标题】:Use `dplyr` or `purrr` to modify a row element conditional on another row element?使用 `dplyr` 或 `purrr` 来修改以另一个行元素为条件的行元素?
【发布时间】:2020-11-25 05:33:19
【问题描述】:

我正在尝试修改一行的多个元素,条件是该行中的另一个元素。

我能够使用双 for 循环(见下文)实现我想要的输出,但由于我知道 R 是为矢量化操作而构建的,所以这可能不是正确的方法。使用 tidyverse 工具(例如 dplyrpurrr)是否有更清洁/更有效的方法?

我认为rowwise()across()mutate() 的某种组合可能会起作用,但我无法做到。

# Define Data
df <- head(mtcars)
    
# Modify Data
for (i in 1:nrow(df)) {
  for (col in c("mpg", "cyl", "disp", "hp")) {
    df[i,][col] <- ifelse(df[i,]['carb'] == 4,
                          df[i,][col] * 100,
                          df[i,][col])
  }
}
# Before
                       mpg cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
# After
                     mpg cyl  disp    hp drat    wt  qsec vs am gear carb
Mazda RX4         2100.0 600 16000 11000 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     2100.0 600 16000 11000 3.90 2.875 17.02  0  1    4    4
Datsun 710          22.8   4   108    93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive      21.4   6   258   110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout   18.7   8   360   175 3.15 3.440 17.02  0  0    3    2
Valiant             18.1   6   225   105 2.76 3.460 20.22  1  0    3    1

【问题讨论】:

    标签: r dplyr purrr data-cleaning


    【解决方案1】:

    试试这个

    library(dplyr)
    mtcars %>% mutate(across(c("mpg", "cyl", "disp", "hp"), ~if_else(carb == 4, 100 * ., .)))
    

    输出

          mpg cyl    disp    hp drat    wt  qsec vs am gear carb
    1  2100.0 600 16000.0 11000 3.90 2.620 16.46  0  1    4    4
    2  2100.0 600 16000.0 11000 3.90 2.875 17.02  0  1    4    4
    3    22.8   4   108.0    93 3.85 2.320 18.61  1  1    4    1
    4    21.4   6   258.0   110 3.08 3.215 19.44  1  0    3    1
    5    18.7   8   360.0   175 3.15 3.440 17.02  0  0    3    2
    6    18.1   6   225.0   105 2.76 3.460 20.22  1  0    3    1
    7  1430.0 800 36000.0 24500 3.21 3.570 15.84  0  0    3    4
    8    24.4   4   146.7    62 3.69 3.190 20.00  1  0    4    2
    9    22.8   4   140.8    95 3.92 3.150 22.90  1  0    4    2
    10 1920.0 600 16760.0 12300 3.92 3.440 18.30  1  0    4    4
    11 1780.0 600 16760.0 12300 3.92 3.440 18.90  1  0    4    4
    12   16.4   8   275.8   180 3.07 4.070 17.40  0  0    3    3
    13   17.3   8   275.8   180 3.07 3.730 17.60  0  0    3    3
    14   15.2   8   275.8   180 3.07 3.780 18.00  0  0    3    3
    15 1040.0 800 47200.0 20500 2.93 5.250 17.98  0  0    3    4
    16 1040.0 800 46000.0 21500 3.00 5.424 17.82  0  0    3    4
    17 1470.0 800 44000.0 23000 3.23 5.345 17.42  0  0    3    4
    18   32.4   4    78.7    66 4.08 2.200 19.47  1  1    4    1
    19   30.4   4    75.7    52 4.93 1.615 18.52  1  1    4    2
    20   33.9   4    71.1    65 4.22 1.835 19.90  1  1    4    1
    21   21.5   4   120.1    97 3.70 2.465 20.01  1  0    3    1
    22   15.5   8   318.0   150 2.76 3.520 16.87  0  0    3    2
    23   15.2   8   304.0   150 3.15 3.435 17.30  0  0    3    2
    24 1330.0 800 35000.0 24500 3.73 3.840 15.41  0  0    3    4
    25   19.2   8   400.0   175 3.08 3.845 17.05  0  0    3    2
    26   27.3   4    79.0    66 4.08 1.935 18.90  1  1    4    1
    27   26.0   4   120.3    91 4.43 2.140 16.70  0  1    5    2
    28   30.4   4    95.1   113 3.77 1.513 16.90  1  1    5    2
    29 1580.0 800 35100.0 26400 4.22 3.170 14.50  0  1    5    4
    30   19.7   6   145.0   175 3.62 2.770 15.50  0  1    5    6
    31   15.0   8   301.0   335 3.54 3.570 14.60  0  1    5    8
    32   21.4   4   121.0   109 4.11 2.780 18.60  1  1    4    2
    

    【讨论】:

      【解决方案2】:

      您实际上可以直接在数据帧上执行此计算。

      df <- head(mtcars)
      cols <- c("mpg", "cyl", "disp", "hp")
      df[cols] <- df[cols] * c(1, 100)[(df$carb == 4) + 1]
      #Or to be clear you can use `ifelse`
      #df[cols] <- df[cols] * ifelse(df$carb == 4, 100, 1)
      df
      
      #                     mpg cyl  disp    hp drat   wt qsec vs am gear carb
      #Mazda RX4         2100.0 600 16000 11000 3.90 2.62 16.5  0  1    4    4
      #Mazda RX4 Wag     2100.0 600 16000 11000 3.90 2.88 17.0  0  1    4    4
      #Datsun 710          22.8   4   108    93 3.85 2.32 18.6  1  1    4    1
      #Hornet 4 Drive      21.4   6   258   110 3.08 3.21 19.4  1  0    3    1
      #Hornet Sportabout   18.7   8   360   175 3.15 3.44 17.0  0  0    3    2
      #Valiant             18.1   6   225   105 2.76 3.46 20.2  1  0    3    1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-14
        • 1970-01-01
        • 2021-10-13
        相关资源
        最近更新 更多