У меня довольно большой data.frame с несколькими тысячами строк и несколькими десятками столбцов. Некоторые строки имеют значения NA в последних столбцах. Пример df:

          pos1    pos2    pos3    pos4    pos5    pos6    
case1     0.5     0.6     0.5     0.3     0.2      NA
case2     0.3     0.7     0.2     0.1     0.5      0.5
case3     0.1     0.2     0.6     0.8     NA       NA
case4     0.4     0.1     0.1     0.6     0.3      0.9
  . 
  .
  .

Более того, мне нужно вектор индексов i1 и i2:

I1:

[1] 2 3 2 1

I2:

[1] 5 4 5 6

Я хотел бы сделать подмножество каждой строки data.frame в соответствии с диапазоном, определенным индексами в i1 и i2. Скажем, я хочу получить список векторов или второй data.frame, где каждый вектор или строка является строкой исходного data.frame, отфильтрованным в соответствии с i1: 12 и, возможно, заполнением пробелов с помощью NA, если выход является data.frame.

Желаемый результат будет:

Список векторов:

[[1]] 
[1] 0.6 0.5 0.3 0.2
[[2]]
[1] 0.2 0.1
[[3]]
[1] 0.2 0.6 0.8 NA
[[4]]
[1] 0.4 0.1 0.1 0.6 0.3 0.9

Data.frame:

          pos1    pos2    pos3    pos4    pos5    pos6    
case1     NA      0.6     0.5     0.3     0.2      NA
case2     NA      NA      0.2     0.1     NA       NA
case3     NA      0.2     0.6     0.8     NA       NA
case4     0.4     0.1     0.1     0.6     0.3      0.9
  . 
  .
  .

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

subset <- df[cbind(seq_along(i1),i1)]

Но я не могу получить правильный код для выполнения чего-то похожего, но с использованием диапазона значений, разделенных двумя индексами.

Пожалуйста, мне нужна помощь. Большое спасибо.

1
Emilio Mármol Sánchez 9 Фев 2021 в 19:21

1 ответ

Лучший ответ

Мы можем использовать Map

Map(function(x, i, j) x[i:j], asplit(df, 1), i1, i2)

-вывод

#$case1
#pos2 pos3 pos4 pos5 
# 0.6  0.5  0.3  0.2 

#$case2
#pos3 pos4 
# 0.2  0.1 

#$case3
#pos2 pos3 pos4 pos5 
# 0.2  0.6  0.8   NA 

#$case4
#pos1 pos2 pos3 pos4 pos5 pos6 
# 0.4  0.1  0.1  0.6  0.3  0.9 

Для второго случая

do.call(rbind, Map(function(x, i, j) replace(x, !seq_along(x) %in%
          i:j, NA), asplit(df, 1), i1, i2))

-вывод

#      pos1 pos2 pos3 pos4 pos5 pos6
#case1   NA  0.6  0.5  0.3  0.2   NA
#case2   NA   NA  0.2  0.1   NA   NA
#case3   NA  0.2  0.6  0.8   NA   NA
#case4  0.4  0.1  0.1  0.6  0.3  0.9

Данные

df <- structure(list(pos1 = c(0.5, 0.3, 0.1, 0.4), pos2 = c(0.6, 0.7, 
0.2, 0.1), pos3 = c(0.5, 0.2, 0.6, 0.1), pos4 = c(0.3, 0.1, 0.8, 
0.6), pos5 = c(0.2, 0.5, NA, 0.3), pos6 = c(NA, 0.5, NA, 0.9)),
class = "data.frame", row.names = c("case1", 
"case2", "case3", "case4"))

i1 <- c(2, 3, 2, 1)

i2 <- c(5, 4, 5, 6)
0
akrun 9 Фев 2021 в 16:23