[英]For loop using names of a dataframe in R
我正在 dataframe 中按地區 (3) 處理來自我國的 COVID-19 數據。 我想使用這些積極案例的列來生成其他列,我想在這些列中計算行之間的增長。 dataframe:
> 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])
}
我想要的output是下一個:
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
提前致謝。
我們可以across
dplyr
中使用mutate
,因為_all/_at
后綴已被棄用,並且across
較新的版本中,cross 更加通用
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 - 值向量
lag(df[1])
# Lima
#1 NA
返回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"))
在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
或shift
data.table
library(data.table)
setDT(df)[, (paste0(names(df), '_diff')) := .SD - shift(.SD)]
你幾乎擁有它。
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。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.