Я хотел бы создать новые столбцы с возрастающими числами в имени (dist100
, dist200
, dist300
) в df
с условием if/else, которое оценивает значение из dist
(1 = истина; 0 = ложь).
df_desire
— желаемый результат.
df <- tibble(ID=c(1001, 1002, 1003, 1004), dist=c(200, 400, 100, 300))
df_desire <- tibble(ID=c(1001, 1002, 1003, 1004), dist=c(200, 400, 100, 300), dist100=c(0, 0, 1, 0), dist200=c(1, 0, 1, 0), dist300=c(1, 0, 1, 1))
Я попытался использовать следующий код, но получаю сообщение об ошибке:
df_output <- df %>%
mutate(
paste0("dist", seq(100, 300, by = 100)) = ifelse(dist <= paste0("dist", seq(100, 300, by = 100)), 1, 0))
Error: unexpected '=' in:
" mutate(
paste0("dist", seq(100, 300, by = 100)) = "
несколько способов сделать это, но rename_with
действительно удобен в зависимости от контекста
rename_with
, чтобы выбрать столбцы, которые вы хотите переименоватьdf %>%
mutate(a=ifelse(dist==100,1,0),
b=ifelse(dist<=200,1,0),
c=ifelse(dist<=300,1,0)) %>%
rename_with(.cols = -c(1:2), #use tidyselect verbs to select the cols you wan to rename
.fn = ~glue::glue("dist{seq(100,300,by=100)}"))
Вдохновленный приведенным выше ответом (поскольку он меня чему-то научил), я показываю альтернативный подход с аккуратными пакетами. Не так читаемо, но эффективно.
df[,c(glue::glue("dist{seq(100,300,by=100)}"))] <- map(seq(100,300,by=100),~as.numeric(df$dist<=.x))
Вы можете сделать что-то вроде этого:
new_cols = lapply(seq(100,300,100), \(x) as.numeric(df$dist<=x))
names(new_cols) <- paste0("dist",seq(100,300,100))
bind_cols(df,as.data.frame(new_cols))
ID dist dist100 dist200 dist300
<dbl> <dbl> <dbl> <dbl> <dbl>
1 1001 200 0 1 1
2 1002 400 0 0 0
3 1003 100 1 1 1
4 1004 300 0 0 1
Или аналогично внутри одного пайплайна можно сделать так:
vals = seq(100,300,100)
bind_cols(
df,
map(vals, \(x) 1*(df$dist<=x)) %>% setNames(paste0("dist",vals)))
)
data.table
вариант
library(data.table)
vals <- seq(100, 300, by = 100)
cols <- paste0("dist", vals)
setDT(df)
df[, (cols) := lapply(vals, function(x) +(dist <= x))]
df
# ID dist dist100 dist200 dist300
#1: 1001 200 0 1 1
#2: 1002 400 0 0 0
#3: 1003 100 1 1 1
#4: 1004 300 0 0 1