R: как удалить указанную c запись в списке - PullRequest
0 голосов
/ 06 мая 2020
mylist <- list(
    left = structure(list(y = -10, x = 10, grad = -10.5), row.names = 1L, class = "data.frame"), 
    right = list(
        left = structure(list(y = c(7, 8), x = c(20, 25), grad = c(6.5, 7.5)), row.names = 2:3, class = "data.frame"), 
        right = structure(list(y = -7, x = 35, grad = -7.5), row.names = 4L, class = "data.frame"), 
        check_val = 140.166666666667), 
    check_val = 120.333333333333
)

У меня есть объект list, который выглядит следующим образом:

> mylist
$left
    y  x  grad
1 -10 10 -10.5

$right
$right$left
  y  x grad
2 7 20  6.5
3 8 25  7.5

$right$right
   y  x grad
4 -7 35 -7.5

$right$check_val
[1] 140.1667


$check_val
[1] 120.3333

В моем списке хранится check_val. Я хочу проверить каждый из этих check_val, и если значение> 130, я хочу удалить соответствующий подсписок.

В mylist я сначала проверил бы mylist$righ$check_val и увидел бы 140.1667 > 130, поэтому я хочу удалить весь подсписок mylist$right. Затем я проверяю mylist$check_val и обнаруживаю, что 120.333 < 130, поэтому я не буду ничего удалять.

Я хочу, чтобы окончательный результат был

> output
$left
    y  x  grad
1 -10 10 -10.5

$check_val
[1] 120.3333

Возможно, что mylist может иметь много подсписок, то есть check_val может быть встроен в mylist$right$right$right$left$right$check_val,, поэтому я хотел написать код, который позаботится об этих случаях. Это то, что у меня есть до сих пор, но не дает правильного вывода. Может ли кто-нибудь указать мне в правильном направлении?

for(i in 2:length(mylist)){
  print(i)
  if(length(mylist[[i]]) == 1){
    if(mylist[[i]] > 130){
      mylist[[i]] <- NULL
    }else mylist[[i]] = mylist[[i]]
  }else if(length(mylist[[i]]) > 1){
    if(mylist[[i]]$check_val > 130){
      mylist[[i]] <- NULL
    }else mylist[[i]] = mylist[[i]]
  }
}

@@@@@@@@@@@@@@@@ РЕДАКТИРОВАТЬ @@@@@@@@@@@@@ @@

Предположим, теперь у меня есть mylist2

mylist2 <- list(left = structure(list(y = -10, x = 10, grad = -10.5, sim_score = 110.25, 
    output = -10.5, criterion = "x < 15"), row.names = 1L, class = "data.frame"), 
    right = list(left = structure(list(y = c(7, 8), x = c(20, 
    25), grad = c(6.5, 7.5), sim_score = c(98, 98), output = c(7, 
    7), criterion = c("x < 30", "x < 30")), row.names = 2:3, class = "data.frame"), 
        right = structure(list(y = -7, x = 35, grad = -7.5, sim_score = 56.25, 
            output = -7.5, criterion = "x >= 30"), row.names = 4L, class = "data.frame"), 
        root = list(root = structure(list(y = c(7, 8, -7), x = c(20, 
        25, 35), grad = c(6.5, 7.5, -7.5), sim_score = c(14.0833333333333, 
        14.0833333333333, 14.0833333333333), output = c(2.16666666666667, 
        2.16666666666667, 2.16666666666667), criterion = c("x >= 15", 
        "x >= 15", "x >= 15")), row.names = 2:4, class = "data.frame"), 
            check_val = 140.166666666667)), root = list(root = structure(list(
        y = c(-10, 7, 8, -7), x = c(10, 20, 25, 35), grad = c(-10.5, 
        6.5, 7.5, -7.5), sim_score = c(4, 4, 4, 4)), row.names = c(NA, 
    -4L), class = "data.frame"), check_val = 120.333333333333))

, а использование clean_list возвращает следующее:

> clean_list(mylist2, M = 130)
$left
    y  x  grad sim_score output criterion
1 -10 10 -10.5    110.25  -10.5    x < 15

$right
$right$left
  y  x grad sim_score output criterion
2 7 20  6.5        98      7    x < 30
3 8 25  7.5        98      7    x < 30

$right$right
   y  x grad sim_score output criterion
4 -7 35 -7.5     56.25   -7.5   x >= 30


$root
$root$root
    y  x  grad sim_score
1 -10 10 -10.5         4
2   7 20   6.5         4
3   8 25   7.5         4
4  -7 35  -7.5         4

$root$check_val
[1] 120.3333

Однако в идеале я бы хотел

$left
    y  x  grad sim_score output criterion
1 -10 10 -10.5    110.25  -10.5    x < 15

$root
$root$root
    y  x  grad sim_score
1 -10 10 -10.5         4
2   7 20   6.5         4
3   8 25   7.5         4
4  -7 35  -7.5         4

$root$check_val
[1] 120.3333

Есть ли способ изменить clean_list, чтобы удалить весь подсписок mylist2$right?

1 Ответ

4 голосов
/ 06 мая 2020

Я думаю, это дает то, что вы хотите - обратите внимание, что я специально потребовал пропустить элементы data.frame (так что любое вложение check_val внутри data.frame будет go незамеченным)

THRESHOLD = 130
clean_list = function(x, M = THRESHOLD) {
  if (is.data.frame(x) || !is.list(x)) return(x)
  if ('check_val' %in% names(x) && x$check_val > M) return(NULL)
  out = lapply(x, clean_list)
  out[lengths(out) > 0L]
}

clean_list(mylist)
# $left
#     y  x  grad
# 1 -10 10 -10.5

# $check_val
# [1] 120.3333
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...