Заменить значения в нескольких столбцах на значения другого столбца при условии - PullRequest
0 голосов
/ 13 марта 2020

У меня есть кадр данных, похожий на этот:

> var1<-c("01","01","01","02","02","02","03","03","03","04","04","04")
> var2<-c("0","4","6","8","3","2","5","5","7","7","8","9")
> var3<-c("07","41","60","81","38","22","51","53","71","72","84","97")
> var4<-c("107","241","360","181","238","222","351","453","171","372","684","197")
> df<-data.frame(var1,var2,var3,var4)
> df
   var1 var2 var3 var4
1    01    0   07  107
2    01    4   41  241
3    01    6   60  360
4    02    8   81  181
5    02    3   38  238
6    02    2   22  222
7    03    5   51  351
8    03    5   53  453
9    03    7   71  171
10   04    7   72  372
11   04    8   84  684
12   04    9   97  197

Я хочу заменить все значения переменных var2,var3,var4 на "0", которые существуют, где var1 равно 02 и / или 03. Число di git также должно быть таким же, чтобы df выглядело так:

   var1 var2 var3 var4
1    01    0   07  107
2    01    4   41  241
3    01    6   60  360
4    02    0   00  000
5    02    0   00  000
6    02    0   00  000
7    03    0   00  000
8    03    0   00  000
9    03    0   00  000
10   04    7   72  372
11   04    8   84  684
12   04    9   97  197

Теперь я также должен быть уверен, что команда будет выполнена, даже если var1 будет не содержит 02 или 03. По существу, что-то вроде того, если var1 содержит 01 или 02, установите соответствующие значения в var2, var3 и var4 в 0 в соответствии с количеством цифр в var2, var3 и var4 (например, 97 будет 00 и 197 будет 000), а если нет, ничего не делать.

Есть предложения?

Ответы [ 3 ]

1 голос
/ 13 марта 2020

Если вы хотите, чтобы он автоматически делал столько нулей, сколько цифр в переменной, вы можете использовать что-то вроде этого

# define a function
val_to_zero <- function(con, val){ifelse(con, paste0(rep(0,unique(nchar(as.character(val)))), collapse=""),val)}
# define the condition
con <- df$var1 %in% c("01", "02")
# choose which columns to change
vars <- names(df)[2:4]
# apply the function to columns    
df[ , vars] <- do.call("cbind.data.frame", lapply(df[, vars],function(var_i){val_to_zero(con, var_i)}))
# done
df

Для этой функции вам не нужно указывать вручную, сколько нулей нужно использовать для какой колонки. Поэтому, если var5 равно c("292992", ...), оно все еще работает.

1 голос
/ 13 марта 2020

Вот идея, где мы можем сделать это динамически для любого количества столбцов, для любого количества цифр. Хитрость заключается в том, чтобы убедиться, что у вас есть символьные переменные (вместо факторов) и использовать sprintf на основе максимального nchar каждого столбца, то есть

#Convert to character (IF they are factors)
df[] <- lapply(df, as.character)
#Convert values to 0 as per your condition
df[df$var1 %in% c('02', '03'), -1] <- 0
#Add leading 0s to bring to same format as original
df[-1] <- mapply(function(x, y){i1 <- sprintf(paste0('%0', x, 's'), y); gsub(' ', '0', i1)}, 
                               sapply(df[-1], function(i)max(nchar(i))), df[-1])

, что дает

   var1 var2 var3 var4
1    01    0   07  107
2    01    4   41  241
3    01    6   60  360
4    02    0   00  000
5    02    0   00  000
6    02    0   00  000
7    03    0   00  000
8    03    0   00  000
9    03    0   00  000
10   04    7   72  372
11   04    8   84  684
12   04    9   97  197
1 голос
/ 13 марта 2020

Одним из решений является использование mutate и case_when из dplyr

library(dplyr)

df <- df %>%
  mutate(var2 = case_when(var1 %in% c('02','03') ~ '0',
                          TRUE ~ as.character(var2)),
         var3 = case_when(var1 %in% c('02','03') ~ '00',
                          TRUE ~ as.character(var3)),
         var4 = case_when(var1 %in% c('02','03') ~ '000',
                          TRUE ~ as.character(var4)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...