简体   繁体   English

如何在不使用列号的情况下将函数应用于两个按顺序标记的变量系列?

[英]How to apply a function over two series of sequentially labelled variables without using column numbers?

I need to apply a function using two sets of sequentially labelled variables and attach the new set of variables to the data frame.我需要使用两组按顺序标记的变量应用一个函数,并将新的一组变量附加到数据框。 I need to do this without referring to the column numbers in the code.我需要在不参考代码中的列号的情况下执行此操作。

More specifically, here is the simple task I am trying to do:更具体地说,这是我正在尝试执行的简单任务:

dat <- data.frame(sec1 = sample(c(0:3),10,replace=T) , sec2 = sample(c(0:4),replace=T) , sec3 = sample(c(0:4),replace=T),pri1 = sample(c(0:3),10,replace=T) , pri2 = sample(c(0:4),replace=T) , pri3 = sample(c(0:4),replace=T) )
dat$rel1 <- ifelse(dat$pri1>0,dat$sec1/dat$pri1,NA)
dat

I want to repeat the "ifelse" function shown above without typing it repeatedly for each set of variables.我想重复上面显示的“ifelse”函数,而不是为每组变量重复键入它。

I must say, I asked similar questions and received helpful answers ( eg1 and eg2 ) previously but in those case the responses either used the column number in the code, or the example was on a single set of sequentially labelled variable.我必须说,我之前问过类似的问题并收到了有用的答案( eg1eg2 ),但在这种情况下,响应要么使用代码中的列号,要么示例位于一组按顺序标记的变量上。 I could not manage to revise the suggested code to solve this particular problem.我无法修改建议的代码来解决这个特定问题。

Any suggestion is very much appreciated.非常感谢任何建议。

dat_n <- cbind(dat, mapply(function(x, y) ifelse(y>0,x/y,NA) ,dat[grepl("sec",names(dat))], dat[grepl("pri",names(dat))]))
> dat_n
   sec1 sec2 sec3 pri1 pri2 pri3      rel1      sec1      sec2 sec3
1     2    1    2    3    3    0 0.6666667 0.6666667 0.3333333   NA
2     3    3    4    0    2    4        NA        NA 1.5000000 1.00
3     1    0    3    1    4    4 1.0000000 1.0000000 0.0000000 0.75
4     2    4    1    3    3    2 0.6666667 0.6666667 1.3333333 0.50
5     2    0    2    3    4    1 0.6666667 0.6666667 0.0000000 2.00
6     1    1    2    1    3    0 1.0000000 1.0000000 0.3333333   NA
7     1    3    4    0    2    4        NA        NA 1.5000000 1.00
8     1    0    3    1    4    4 1.0000000 1.0000000 0.0000000 0.75
9     3    4    1    2    3    2 1.5000000 1.5000000 1.3333333 0.50
10    1    0    2    2    4    1 0.5000000 0.5000000 0.0000000 2.00

You could use Vectorize on an ifelse and clean this up a lot您可以在ifelse上使用Vectorizeifelse进行大量清理

set.seed(1)
dat <- data.frame(sec1 = sample(c(0:3),10,replace=T) , sec2 = sample(c(0:4),replace=T) , sec3 = sample(c(0:4),replace=T),pri1 = sample(c(0:3),10,replace=T) , pri2 = sample(c(0:4),replace=T) , pri3 = sample(c(0:4),replace=T) )
dat$rel1 <- ifelse(dat$pri1>0,dat$sec1/dat$pri1,NA)
dat

f <- Vectorize(function(x, y) ifelse(y > 0, x / y, NA))


f(dat[1:3], dat[4:6])

#           sec1 sec2      sec3
# [1,]  0.3333333 0.50 0.6666667
# [2,]         NA 0.00 1.0000000
# [3,]  1.0000000 1.50        NA
# [4,]         NA   NA 0.3333333
# [5,]  0.0000000 0.75 1.5000000
# [6,]  3.0000000 0.50 0.6666667
# [7,]         NA 0.00 1.0000000
# [8,]  2.0000000 1.50        NA
# [9,]  0.6666667   NA 0.3333333
# [10,] 0.0000000 0.75 1.5000000

v <- lapply(c('sec','pri'), function(x) grep(x, names(dat)))

cbind(dat, `colnames<-`(f(dat[v[[1]]], dat[v[[2]]]), paste0('rel',1:3)))

#    sec1 sec2 sec3 pri1 pri2 pri3      rel1      rel1 rel2      rel3
# 1     1    1    2    3    2    3 0.3333333 0.3333333 0.50 0.6666667
# 2     1    0    3    0    2    3        NA        NA 0.00 1.0000000
# 3     2    3    4    2    2    0 1.0000000 1.0000000 1.50        NA
# 4     3    1    1    0    0    3        NA        NA   NA 0.3333333
# 5     0    3    3    1    4    2 0.0000000 0.0000000 0.75 1.5000000
# 6     3    1    2    1    2    3 3.0000000 3.0000000 0.50 0.6666667
# 7     3    0    3    0    2    3        NA        NA 0.00 1.0000000
# 8     2    3    4    1    2    0 2.0000000 2.0000000 1.50        NA
# 9     2    1    1    3    0    3 0.6666667 0.6666667   NA 0.3333333
# 10    0    3    3    1    4    2 0.0000000 0.0000000 0.75 1.5000000

(yo dawg I heard you like to vectorize so we put some Vectorize in your vectorized so you can Vectorize while you vectorize) (哟,天啊,我听说你喜欢矢量化,所以我们在你的矢量Vectorize中放了一些Vectorize ,这样你就可以在Vectorize同时进行矢量化)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何对数据框中按顺序标记的变量应用简单函数? - How to apply simple functions on sequentially labelled variables in a data frame? 如何使用 mapply 将两个数字列表应用到 function 中? - How to apply two list of numbers into a function using mapply? 如何在名称中包含特定字符串的一系列列上应用相同的函数? - How to apply the same function over a series of columns with a specific string in their names? 如何在列上应用具有多个参数的函数? - How to apply a function with multiple arguments over a column? 如何传递列变量来应用函数? - How to pass column variables to apply function? 如何使用 dplyr 在以 .x 和 .y 结尾的一组变量中应用具有两个变量的函数(x,y) - how to apply a function(x,y) with two variables across set of variables ending with .x and .y using dplyr 在“网格搜索”一系列组合中应用功能 - Apply function over a 'grid search' series of combinations 如何在将来的索引号上应用功能-XTS对象 - How to apply function over future index numbers - xts object R:避免使用 for 循环顺序选择一列中的值并使用另一列中的值向量应用函数 - R: Avoid using a for-loop to sequentially select values in one column and apply a function using the vector of values in another column Apply()用于具有两个参数的函数 - Apply() for a function with two parameters to apply over
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM