【问题标题】:How to apply a function to each element of a vector in R如何将函数应用于R中向量的每个元素
【发布时间】:2012-12-21 19:15:59
【问题描述】:

假设我想将向量的每个偶数元素乘以 2,向量的每个奇数元素乘以 3。下面是一些可以执行此操作的代码:

v <- 0:10

idx <- v %% 2 == 0
v[idx] <- v[idx] * 2
v[!idx] <- v[!idx] * 3

如果我有两个以上的案例,这将变得很困难。似乎 apply 系列函数从不处理向量,所以我不知道解决这个问题的更好方法。如果我对数据进行转换,也许使用 apply 函数会起作用,但似乎这不应该是我解决这个简单问题所需要做的事情。

有什么想法吗?

编辑:很抱歉造成混乱。我对“%%”运算符并不特别感兴趣。我想在我的问题中加入一些具体的代码,但是根据对问题的回答,太具体了。我想弄清楚如何对列表的每个成员应用一些任意函数。这对于 apply() 是不可能的,我认为 sapply() 只适用于列表。

【问题讨论】:

  • 你有什么建议?您可以在多种情况下使用 switch 之类的东西。您当然可以在向量上使用apply 系列:sapply(v, function(x) x + 1)。但我不明白你是如何摆脱使用一个你必须确定事情属于哪种情况的结构......
  • 不清楚您所说的“如果我有两个以上的案例”是什么意思。您是否正在寻找可以使用 v %% n where n &gt; 2 的东西?
  • 谢谢,贾斯汀。 sapply 完全按照您的描述工作,这正是我想要的。我正在查看 apply 系列函数的教程,并认为 sapply 只能列出一个列表。

标签: r vector apply


【解决方案1】:

你可以使用向量乘法来做你想做的事:

tmp <- 1:10
tmp * rep(c(3,2), length(tmp)/2)

这很容易扩展到三种或更多情况:

tmp * rep(c(3,2,4), length(tmp)/3)

【讨论】:

  • 或更好,使用回收:tmp * c(3,2,4)。 (请注意,如果长度关闭,这两种方法都会发出警告。)
【解决方案2】:

你可以这样做:

v <- v * c(2, 3)[v %% 2 + 1]

它可以推广到任何v %% n,例如:

v <- v * c(2, 3, 9, 1)[v %% 4 + 1]

此外,它不要求 length(v)n 的倍数。

【讨论】:

  • 不错!如果您更改矢量的顺序,您甚至可以删除选择:v * c(2, 3, 9, 1)[v %% 4 + 1] == v * c(3, 9, 1, 2)
  • @Tyler,如果length(n) 不是您引用的示例中4 的倍数,则选择是为了避免任何警告。
【解决方案3】:

最简单的是:

v*c(2,3) # as suggested by flodel in a comment.

要在文档中搜索的术语是“参数回收”...... R 语言的一个特性。仅适用于二元中缀函数(请参阅?Ops)。对于一些参数不会出错的非二元向量化函数,并且您不能依赖“v”的结构非常规则,您可以使用 ifelse:

ifelse( (1:length(v)) %% 2 == 0, func1(v), func2(v) )

这会构造两个向量,然后根据第一个参数的真值选择第一个或第二个中的元素。如果您试图回答帖子标题中的问题,那么您应该查看:

?sapply

【讨论】:

  • 谢谢,像这样使用 sapply 可以: sapply(v, function(x) if(x %% 2 == 0) return(x * 2) else return(x * 3))跨度>
  • 如果使用更大的向量,这将比第一个要慢得多,但它的主要优势是它不依赖于“x”值的排列。它也将比我现在建议的要慢。 (构建一个与真实案例一样复杂的测试示例是一个好习惯。)ifelse( x %% 2 == 0, x^2, x^3 ) 会比您的代码快得多。
【解决方案4】:

这是一个答案,允许将任意一组函数应用于向量中的已定义组。

# source data
test <- 1:9
# categorisations of source data
cattest <- rep(1:3,each=3)
#[1] 1 1 1 2 2 2 3 3 3

使函数差分应用函数:

categ <- function(x,catg) {
          mapply(
                 function(a,b) {
                                switch(b,
                                       a * 2,
                                       a * 3,
                                       a / 2
                                      )
                               },
                  x,
                  catg
                 )
         }
# where cattest = 1, multiply by 2
# where cattest = 2, multiply by 3
# where cattest = 3, divide by 2

结果:

categ(test,cattest)
#[1]  2.0  4.0  6.0 12.0 15.0 18.0  3.5  4.0  4.5

【讨论】:

    猜你喜欢
    • 2017-05-01
    • 1970-01-01
    • 2013-08-28
    • 2022-11-02
    • 2013-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-13
    相关资源
    最近更新 更多