Как индексировать определенные строки и столбцы фрейма данных по условиям с помощью R?

#r #dataframe #variables #indexing #conditional-statements

Вопрос:

У меня есть два фрейма данных с разными размерами; фрейм данных a и фрейм данных b. Я хочу заменить определенные поля в фрейме данных a значениями полей, хранящихся в фрейме данных b. Я нашел способ, как отфильтровать значение кадра данных b, которое я хочу использовать для замены полей кадра данных a. Однако я не знаю, как индексировать конкретные поля фрейма данных a, используя условия для замены там значений… Есть какие-нибудь предложения?

 df_a <- base::cbind(base::as.data.frame(
                    base::matrix(c(3, 5, 6, 1, 23, 6, 7, 58, 9), ncol = 3)),
                    c('bli', 'bla', 'blub'))
# create dataframe a

base::colnames(df_a) <- c('col1', 'col2', 'col3', 'col4')
# set colnames of dataframe a

df_b <- base::as.data.frame(base::matrix(base::seq(1, 27, 3), ncol = 3, byrow = TRUE))
# create dataframe b

repl_val <- df_b[2, 2]
# replace value for dataframe a

spc_col1_val <- 5
# row to index dataframe a: column <col1> should have the value <5>
spc_col <- base::paste0('col', '1')
# column to index dataframe a: the specific column is combined out of different variables e.g. <col> and <3>

df_a[df_a$col1 == spc_col1_val, df_a$spc_col] <- repl_val
# THIS DOES NOT WORK
 

Комментарии:

1. df_b не правильно определено. а ) отсутствует. Но даже если вы добавите a ) , это не решит проблему. df_b будет a data.frame с одним столбцом, что означает repl_val , что он будет пустым, так как записи нет df_b[2, 2] .

2. Почему вы «расширяете пространство имен» базового пакета? В чем преимущество этого стиля?

3. @Mischa большое спасибо за ваши замечания, я изменил код, чтобы он имел смысл.

4. @dario я пытаюсь «создать пространство имен» для всех пакетов здесь, в stackoverflow, чтобы избежать путаницы. однако вы правы, в данном контексте это излишне, так как я не загружаю дальнейшие пакеты…

Ответ №1:

Поскольку похоже, что вы относительно новичок в R, я попытаюсь дать полный ответ: я настоятельно рекомендую не использовать base:: везде по двум причинам: 1) Никто никогда не собирается выгружать base пакет и б) это выглядит ужасно. Я думаю, что понимаю ваше намерение и что вы согласитесь с тем, что мы должны приложить все усилия, чтобы код был как можно более чистым и разборчивым (чтобы найти/избежать ошибок). Но этот выбор стиля делает его более многословным без каких-либо преимуществ… На самом деле, это затрудняет чтение и понимание кода (как уже указывали комментаторы, в этих нескольких строках кода было несколько ошибок. И в примере все еще есть ошибки (т. Е. Нет переменной с именем «spc_val_col1» (вы назвали ее «spc_col1_val») ) Использование более чистого стиля очень помогает!!

Теперь, если вас интересует эксплицитность, гораздо более чистый способ создания df_a-это:

 df_a <- data.frame(col1 = c(3, 5, 6),
                   col2 = c(1, 23, 6),
                   col3 = c(7, 58, 9),
                   col4 = c('bli', 'bla', 'blub'))
 

Преимущества: Все это есть, включая colnames, нет необходимости в дальнейших манипуляциях с df, меньше способов внесения ошибок…

Для второго задания вы используете seq и matrix которое может быть полезно. Хотя я не вижу в этом необходимости здесь (опять же, явное лучше, чем неявное) Но as.data.frame здесь это не нужно, только различия будут именами (которые в любом случае не используются)

 df_b <- data.frame(matrix(seq(1, 27, 3), ncol = 3, byrow = TRUE))
  
repl_val <- df_b[2, 2] # replace value for dataframe a
spc_col1_val <- 5 # row to index dataframe a: column <col1> should have the value <5>
 

В комментарии, который вы пишете, объединяются разные переменные, например < col> и< col> <3><3>, но затем вы используете paste0(‘col’, ‘1’)
Я надеюсь, вы понимаете, насколько это сбивает с толку (опять же, если мы заботимся о ясности, было бы действительно полезно исправить все это…)

 spc_col <- paste0('col', '1') # column to index dataframe a: the specific column is combined out of different variables e.g. <col> and <3> 
 

df_a перед назначением:

   col1 col2 col3 col4
1    3    1    7  bli
2    5   23   58  bla
3    6    6    9 blub
 

В следующей строке было несколько ошибок, но самое главное: мы можем использовать which для извлечения индекса элементов, удовлетворяющих условию, и мы указываем имена столбцов непосредственно в виде строки, я бы предложил изучить ?Extract это очень важная функция в R!

 df_a[which(df_a$col1 == spc_col1_val), spc_col] <- repl_val
 

df_a после назначения:

   col1 col2 col3 col4
1    3    1    7  bli
2   13   23   58  bla
3    6    6    9 blub
 

Пожалуйста, не воспринимайте критику как признак враждебности. Я думаю, что у вас правильные намерения, и вы, очевидно, готовы приступить к работе. Но я бы настоятельно рекомендовал сосредоточиться на вещах, которые действительно полезны и важны 😉 Надеюсь, это вам помогло!

И в заключение: было бы здорово, если бы вы также включили пример желаемого результата (я предполагаю, что я показал то, что вы хотели, но пример вывода устранит всю двусмысленность (agian, лучше явно 😉