在R中使用数据框名称进行循环

我正在使用数据框中按地区(3)来自我的国家/地区的COVID-19数据。我想使用那些肯定案例的列来生成其他列,以计算行之间的增长。数据框:

> df
  Lima Arequipa Huánuco
1    1       NA      NA
2    6       NA      NA
3    6        1      NA
4    8        2       5
5    9        3       7
6    11       4       8

I want to use a for loop to calculate in a new column named as each df's column adding to its name "_dif" in which I have the row 1 - lag (row 1) for each column. So I used this code:

for(col in names(df)) {
  df[paste0(col, "_dif")] = df[col] - lag(df[col])
}

我想要的输出是下一个:

  Lima Arequipa Huánuco Lima_dif Arequipa_dif Huánuco_dif
1    1       NA      NA       NA           NA          NA
2    6       NA      NA       5            NA          NA
3    6        1      NA       0            NA          NA
4    8        2       5       2            1           NA
5    9        3       7       1            1           2
6    11       4       8       2            1           1

但是,当我在for循环之后看到df时,我得到了这一点(新列中只有NA):

  Lima Arequipa Huánuco Lima_dif Arequipa_dif Huánuco_dif
1    1       NA      NA       NA           NA          NA
2    6       NA      NA       NA           NA          NA
3    6        1      NA       NA           NA          NA
4    8        2       5       NA           NA          NA
5    9        3       7       NA           NA          NA
6    11       4       8       NA           NA          NA

提前致谢。

评论
  • 也,許
    也,許 回复

    We can just use mutate_all

    library(dplyr)
    df %>%
        mutate_all(list(dif = ~. - lag(.)))
    #   Lima Arequipa Huánuco Lima_dif Arequipa_dif Huánuco_dif
    #1    1       NA      NA       NA           NA          NA
    #2    6       NA      NA        5           NA          NA
    #3    6        1      NA        0           NA          NA
    #4    8        2       5        2            1          NA
    #5    9        3       7        1            1           2
    #6   11        4       8        2            1           1
    

    Or with mutate/across

    df %>%
       mutate(across(everything(), ~ . - lag(.), names = "{col}_dif"))
    #   Lima Arequipa Huánuco Lima_dif Arequipa_dif Huánuco_dif
    #1    1       NA      NA       NA           NA          NA
    #2    6       NA      NA        5           NA          NA
    #3    6        1      NA        0           NA          NA
    #4    8        2       5        2            1          NA
    #5    9        3       7        1            1           2
    #6   11        4       8        2            1           1
    

    Or in base R

    df[paste0(names(df), "_dif")] <- lapply(df, function(x) c(NA, diff(x)))
    

  • 怪叔叔
    怪叔叔 回复

    In dplyr, you can use mutate_all :

    library(dplyr)
    df %>%  mutate_all(list(diff = ~. - lag(.)))
    
    #  Lima Arequipa Huánuco Lima_diff Arequipa_diff Huánuco_diff
    #1    1       NA      NA        NA            NA           NA
    #2    6       NA      NA         5            NA           NA
    #3    6        1      NA         0            NA           NA
    #4    8        2       5         2             1           NA
    #5    9        3       7         1             1            2
    #6   11        4       8         2             1            1
    

    Or shift in data.table

    library(data.table)
    setDT(df)[, (paste0(names(df), '_diff')) := .SD - shift(.SD)]