Возможно ли вернуть значения ссылочных столбцов нескольким столбцам в r

#r #reference

#r #ссылка

Вопрос:

Я организую большой набор данных, адаптированный к моим исследованиям. Предположим, что у меня есть 9 наблюдений (записей) и 4 столбца следующим образом:

 z <- data.frame("fa" = c(1, NA, NA, 2, 1, 1, 2, 1, 1), 
                "fb" = c(2, 2, NA, 1, NA, NA, NA, 1, 2),
                "initial_1" = c("A", "B", "B", "B", "A", "C", "D", "B", "A"),
                "initial_2" = c("D", "C", "C", "A", "B", "A", "A", "D", "D"))

  

Я хочу создать два новых столбца, fa_new и fb_new в соответствии со значениями первых двух столбцов, fa и fb, которые связаны с ссылочными столбцами, initial_1 и initial_2, так что fa == # соответствует intial_ # .

Например, как видно выше, первой записью столбца fa является 1 , которая связана с «A» из intial_ 1 . Таким образом, первой записью нового столбца fa_new будет «A». Аналогично, первая запись fb — это 2 , которая связана с «D» из intial_ 2 ; таким образом, первая запись fb_new будет «D».

Соответственно, мое ожидание:

   fa_new fb_new
1 A      D     
2 NA     C     
3 NA     NA    
4 A      B     
5 A      NA    
6 C      NA    
7 A      NA    
8 B      B     
9 A      D   
  

Возможно ли это с помощью r?

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

1. Спасибо за обновление данных с помощью dput , что многое проясняет. Вы пометили данные. Также обратите внимание, что у вас есть значение -3, которое выдает вам эту ошибку, потому что нет столбца -3. Что вы хотите иметь в качестве значения для таких отрицательных чисел?

2. Отрицательными будут NAs.

3. Проверьте обновленный ответ, если это поможет.

4. Да, это работает! Большое вам спасибо, и я действительно ценю вашу прекрасную помощь!!!

Ответ №1:

Вы можете использовать lapply , чтобы сделать это для нескольких столбцов :

 cols <- 1:2
init_cols <- paste0('initial_', cols)
new_cols <- paste0(names(z)[cols], '_new')
inds <- 1:nrow(z)
z[new_cols] <- lapply(z[cols], function(x) z[init_cols][cbind(inds, x)])
z
#  fa fb initial_1 initial_2 fa_new fb_new
#1  1  2         A         D      A      D
#2 NA  2         B         C   <NA>      C
#3 NA NA         B         C   <NA>   <NA>
#4  2  1         B         A      A      B
#5  1 NA         A         B      A   <NA>
#6  1 NA         C         A      C   <NA>
#7  2 NA         D         A      A   <NA>
#8  1  1         B         D      B      B
#9  1  2         A         D      A      D
  

Логика здесь заключается в том, что мы создаем матрицу с cbind , которая имеет номер строки / столбца. Номер строки равен inds ( 1:nrow(z) ), тогда как номер столбца берется из fa / fb столбцов, которые используются для подмножества z фрейма данных.


Фактический фрейм данных помечен как dataset, следующий ответ должен работать с реальными данными.

 cols <- 1:2
init_cols <- paste0('fuinitials_', 1:94)
new_cols <- paste0(names(z)[cols], '_new')
inds <- 1:nrow(z)

z1 <- data.frame(z)
z1[cols][z1[cols] < 1] <- NA
z1[new_cols] <- lapply(z1[cols], function(x) z1[init_cols][cbind(inds, x)])
  

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

1. Это работает для этого примера, я ценю это! Но это не работает для фактических данных, показывая знак ошибки » Ошибка: индекс cbind (индексы, x) является матрицей, он должен быть типа logical». Фактический набор данных содержит более 40 ссылочных столбцов. Мне интересно, смогу ли я найти решение.

2. Как показано в примере, это должно работать для любого количества столбцов. Я думаю, вам нужно настроить константы в соответствии с вашим фреймом данных. Несколько вещей, которые вам нужно проверить: 1. у cols есть все номера столбцов, для которых вы хотите создать новые столбцы? В вашем примере нам нужно создать новые столбцы для fa и fb , которые являются номерами столбцов 1 и 2. следовательно, cols <- 1:2 вам нужно изменить его на основе ваших данных. 2. Ваши исходные столбцы названы одинаково. В вашем примере это называется как initial_1 и initial_2 я генерирую их с помощью init_cols <- paste0('initial_', cols) . Вы можете проверить?

3. Если у вас возникли проблемы с настройкой ответа на основе ваших данных. Вы можете обновить свой пост с помощью dput(df[1:6, 1:6]) , чтобы у нас были те же данные, что и у вас, вместе с именами столбцов, и мы могли соответствующим образом скорректировать ответ.

4. Да, я протестировал это после изменения 1 и 2, которые вы предложили, но все равно это не работает, показывая ошибку «Ошибка в as.matrix (x) [i]: нижний индекс выходит за рамки». У меня есть вопрос. Могу ли я разделить столбцы fa / fb и ссылки с помощью двух фреймов данных? Например, я создаю данные «y» для столбцов fa и fb и «z» для ссылочных столбцов для создания новых столбцов.

5. Пожалуйста, обновите свой пост данными, используя dput ваши фактические данные, потому что то, что вы показали, не соответствует тому, что у вас есть на самом деле. Таким образом, любые предложения в ответе не будут работать для ваших данных. Если вы получаете ошибку, используя приведенный выше код, мы должны иметь возможность воспроизвести это, чтобы исправить. Поскольку ответ работает для выборочных данных, а не для ваших исходных данных, вам необходимо обновить пример, который похож на ваши исходные данные.