很难描述我的需求,所以我将用一个直观的例子来说明。
我有一个data.frame,它类似于:
foo <- data.frame(
id=c("blah", "foo", "bar"),
minplayers=c(2,3,1),
maxplayers=c(4,4,3),
players1.cash=c(10,20,10),
players2.cash=c(0,10,10),
players3.cash=c(1,0,0),
players4.cash=c(8,8,9)
)
给出如下内容:
+-----+-----+-----+---------------+---------------+---------------+---------------+
|id | min | max | players1.cash | players2.cash | players3.cash | players4.cash |
+-----+-----+-----+---------------+---------------+---------------+---------------+
|blah | 2 | 4 | 10 | 0 | 1 | 8 |
+-----+-----+-----+---------------+---------------+---------------+---------------+
|foo | 3 | 4 | 20 | 10 | 0 | 8 |
+-----+-----+-----+---------------+---------------+---------------+---------------+
|bar | 1 | 3 | 10 | 10 | 0 | 9 |
+-----+-----+-----+---------------+---------------+---------------+---------------+
我需要的是将所有玩家n设置为NA。如果n在 {min,max}间隔之外(对于该行),则为每行提供现金值。在图片:
+-----+-----+-----+---------------+---------------+---------------+---------------+
|id | min | max | players1.cash | players2.cash | players3.cash | players4.cash |
+-----+-----+-----+---------------+---------------+---------------+---------------+
|blah | 2 | 4 | NA | 0 | 1 | 8 |
+-----+-----+-----+---------------+---------------+---------------+---------------+
|foo | 3 | 4 | NA | NA | 0 | 8 |
+-----+-----+-----+---------------+---------------+---------------+---------------+
|bar | 1 | 3 | 10 | 10 | 0 | NA |
+-----+-----+-----+---------------+---------------+---------------+---------------+
换句话说:我只是想让玩家的数字(1到4)在每一行的最小/最大的各自边界。如果是,我想保留球员的价值,如果不是,那就写上NA。
您可以使用vectorized
方法:
ix = grep("^players(\d+)\.cash", names(foo))
numbers = as.numeric(gsub("^players(\d+)\.cash", "\1", names(foo)[ix]))
m = matrix(numbers, ncol=length(ix), nrow=nrow(foo), byrow=T)
foo[ix][!(m>=foo$minplayers & m<=foo$maxplayers)] <-NA
#> foo
# id minplayers maxplayers players1.cash players2.cash players3.cash players4.cash
#1 blah 2 4 NA 0 1 8
#2 foo 3 4 NA NA 0 8
#3 bar 1 3 10 10 0 NA