使用 R 中数据框名称的循环

For loop using names of a dataframe in 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

我想使用 for 循环在一个名为每个 df 列的新列中进行计算,并添加到其名称“_dif”中,其中每一列都有 row 1 - lag (row 1)。所以我使用了这段代码:

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

提前致谢。

dplyr中,您可以使用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

shiftdata.table

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

我们可以将 mutatedplyr 中的 across 一起使用,因为 _all/_at 后缀已被弃用,在较新的版本中,across 更多广义化

library(dplyr)
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

或在base R

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

或者另一种选择是

df[paste0(names(df), "_dif")] <- rbind(NA, diff(as.matrix(df)))

OP 的 for 循环中的问题是 df[col] 仍然是具有单列的 data.frame,我们需要 df[[col]] 提取为 vector 因为 lag 需要一个 vector。根据?lag

x - Vector of values

lag(df[1])
#  Lima
#1   NA

returns NA 它被回收了

同时,

lag(df[[1]])
#[1] NA  1  6  6  8  9

因此,如果我们将代码更改为

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


df
#  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

数据

df <- structure(list(Lima = c(1L, 6L, 6L, 8L, 9L, 11L), Arequipa = c(NA, 
NA, 1L, 2L, 3L, 4L), Huánuco = c(NA, NA, NA, 5L, 7L, 8L)), 
  class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6"))

你几乎成功了。

df <- read_table("V  Lima  Arequipa    Huanuco
1    1       NA      NA
2    6       NA      NA
3    6        1      NA
4    8        2       5
5    9        3       7
6    11       4       8")

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

# A tibble: 6 x 8
      V  Lima Arequipa Huanuco V_dif Lima_dif Arequipa_dif Huanuco_dif
  <dbl> <dbl>    <dbl>   <dbl> <dbl>    <dbl>        <dbl>       <dbl>
1     1     1       NA      NA     1        1           NA          NA
2     2     6       NA      NA     2        6           NA          NA
3     3     6        1      NA     3        6            1          NA
4     4     8        2       5     4        8            2           5
5     5     9        3       7     5        9            3           7
6     6    11        4       8     6       11            4           8

您没有将 lag 的默认值设置为 0,所以它转到了 NA。