在嵌套在数据框中的列表变量中进行子集化和替换

Subsetting and replacing in a list variable nested in a dataframe

这是我的数据框示例。它包括一个名为 "dta" 的列变量,它是我想为每个场景保留的 n 个值的单个列表:

set.seed(777)
df <- data.frame(theo = numeric(),
                 size = numeric(),
                 dta  = I(list()))
df[ 1: 5,"theo"]  <- qlnorm(0.1, meanlog=0, sdlog=1, lower.tail = TRUE, log.p = FALSE)
df[ 6:10,"theo"]  <- qlnorm(0.2, meanlog=0, sdlog=1, lower.tail = TRUE, log.p = FALSE)
df[ 1: 5,"size"]  <- 10
df[ 6:10,"size"]  <- 20
for(i in 1:10){
     df$dta[i] <- list(rlnorm(df$size[i], meanlog = 0, sdlog = 1))
     }
df
str(df)

这应该给出如下 df:

        theo size          dta
1  0.2776062   10 1.631967....
2  0.2776062   10 0.737667....
3  0.2776062   10 0.131252....
4  0.2776062   10 1.937334....
5  0.2776062   10 0.739868....
6  0.4310112   20 4.631176....
7  0.4310112   20 2.610180....
8  0.4310112   20 0.175918....
9  0.4310112   20 3.501670....
10 0.4310112   20 0.588178....

或:

'data.frame':   10 obs. of  4 variables:
 $ theo: num  0.278 0.278 0.278 0.278 0.278 ...
 $ size: num  10 10 10 10 10 20 20 20 20 20
 $ dta :List of 10
  ..$ : num  1.632 0.671 1.667 0.671 5.148 ...
  ..$ : num  0.738 1.056 0.152 0.967 10.089 ...
  ..$ : num  0.131 1.256 0.457 3.574 4.211 ...
  ..$ : num  1.937 2.359 3.496 0.297 4.587 ...
  ..$ : num  0.74 0.66 0.481 0.434 1.874 ...
  ..$ : num  4.631 0.298 10.28 0.933 1.286 ...
  ..$ : num  2.61 0.472 0.251 1.61 0.303 ...
  ..$ : num  0.176 0.566 2.156 0.407 3.52 ...
  ..$ : num  3.502 1.748 1.283 0.648 1.359 ...
  ..$ : num  0.588 0.392 2.447 1.926 0.86 ...
  ..- attr(*, "class")= chr "AsIs"

现在,我想通过以下方式对该列表进行子集化:

  1. 对于每个列表,每个值都与存储在数据帧中的固定值"theo"进行比较
  2. 当该值低于或等于 "theo" 时,则重新编码该值 NA

这是一个有效的代码,它完全符合我的要求:

df$dta2 <- df$dta
for(i in 1:10){
     df$dta2[[i]] [ df$dta2[[i]] <= df$theo[i] ] <- NA
     }

但是我想知道是否有一种方法可以用一行代码获得相同的结果,而不需要 "for loop" 继续有条件地替换嵌套在数据框中的列表中的值?

我们可以使用Map

df$dta3 <- Map(function(x,y) replace(x, x<=y, NA), df$dta, df$theo)
all.equal(df$dta2, df$dta3, check.attributes=FALSE)
#[1] TRUE