#r #for-loop #dplyr #apply
Вопрос:
У меня есть большой набор данных, где каждые 5 столбцов соответствуют измерениям 1 артерии, но назван только первый из пяти столбцов. Пример:
df <- structure(list("agatston", "area", "volume", "density", "mass",
"agatston", "area", "volume", "density", "mass", "agatston",
"area", "volume", "density", "mass"),
.Names = c("Artery_1", NA, NA, NA, NA, "Artery_2", NA, NA, NA, NA, "Artery_3", NA, NA, NA, NA),
row.names = c(NA, -1L),
class = c("tbl_df", "tbl", "data.frame"))
Что выглядит примерно так:
df
# A tibble: 1 x 15
Artery_1 `` `` `` `` Artery_2 `` `` `` `` Artery_3 `` `` `` ``
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 agatston area volume density mass agatston area volume density mass agatston area volume density mass
Я пытаюсь использовать цикл for или применить (), чтобы имена отсутствующих столбцов были заполнены самым последним именем столбца, не отсутствующим. То, чего я пытаюсь достичь, выглядит так:
# A tibble: 1 x 15
Artery_1 Artery_1 Artery_1 Artery_1 Artery_1 Artery_2 Artery_2 Artery_2 Artery_2 Artery_2 Artery_3 Artery_3 Artery_3 Artery_3 Artery_3
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 agatston area volume density mass agatston area volume density mass agatston area volume density mass
Какая-нибудь помощь?
Изменить: В качестве следующего шага я хотел бы сделать столбец не_уникальным, объединив их с именем строки под ним, что приведет к следующему выводу:
# A tibble: 1 x 15
Artery_1_agatson Artery_1_area Artery_1_volume Artery_1_density Artery_1_mass Artery_2_agatson Artery_2_area Artery_2_volume
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 agatston area volume density mass agatston area volume
# ... with 7 more variables: Artery_2_density <chr>, Artery_2_mass <chr>, Artery_3_agatson <chr>, Artery_3_area <chr>,
# Artery_3_volume <chr>, Artery_3_density <chr>, Artery_3_mass <chr>
Ответ №1:
Вы можете использовать zoo::na.locf
для замены NA
значений.
names(df) <- zoo::na.locf(names(df))
names(df)
# [1] "Artery_1" "Artery_1" "Artery_1" "Artery_1" "Artery_1" "Artery_2"
# [7] "Artery_2" "Artery_2" "Artery_2" "Artery_2" "Artery_3" "Artery_3"
#[13] "Artery_3" "Artery_3" "Artery_3"```
Однако не рекомендуется использовать одно и то же имя столбца, поэтому вы можете использовать make.unique
его для создания уникальных имен столбцов.
names(df) <- make.unique(zoo::na.locf(names(df)))
names(df)
# [1] "Artery_1" "Artery_1.1" "Artery_1.2" "Artery_1.3" "Artery_1.4"
# [6] "Artery_2" "Artery_2.1" "Artery_2.2" "Artery_2.3" "Artery_2.4"
#[11] "Artery_3" "Artery_3.1" "Artery_3.2" "Artery_3.3" "Artery_3.4"
Чтобы объединить столбцы с первой строкой, мы можем использовать
names(df) <- paste(zoo::na.locf(names(df)), df[1, ], sep = '_')
names(df)
# [1] "Artery_1_agatston" "Artery_1_area" "Artery_1_volume"
# [4] "Artery_1_density" "Artery_1_mass" "Artery_2_agatston"
# [7] "Artery_2_area" "Artery_2_volume" "Artery_2_density"
#[10] "Artery_2_mass" "Artery_3_agatston" "Artery_3_area"
#[13] "Artery_3_volume" "Artery_3_density" "Artery_3_mass"
Тогда, возможно, отбросьте 1-ю строку с помощью df <- df[-1, ]
.
Комментарии:
1. Спасибо вам за ваш ответ. Чтобы решить проблему с неуникальными именами столбцов: следующим шагом будет сделать их уникальными, объединив их со строкой в строке ниже. Знаете ли вы также, как этого добиться?
2. Я добавил к своему первоначальному вопросу, чтобы было более ясно, чего я пытаюсь достичь.
3. обновленный ответ должен помочь вам в этом.
Ответ №2:
Базовое решение R:
names(df) <- paste(
na.omit(names(df))[cumsum(!(is.na(names(df))))],
df[1,,drop=TRUE],
sep = "_"
)
ИЛИ отбросить первый ряд:
clean_df <- setNames(
df[-1,],
paste(
na.omit(names(df))[cumsum(!(is.na(names(df))))],
df[1,,drop=TRUE],
sep = "_"
)
)