如何使用 tapply 并保留值的顺序

发布于 2024-11-09 11:07:25 字数 515 浏览 0 评论 0原文

希望这不是一个太愚蠢的问题,但作为一个 R 初学者,我对 tapply 有一个严重的问题。可以说

factors <- as.factor( c("a", "b", "c", "a", "b", "c", "a", "b", "c") )
values  <- c( 1, 2, 3, 4, 5, NA, 7, NA, NA )
tapply(
  values,
  factors,
  function(x){
    if( sum(is.na(x)) == 1 ){
      x[ is.na(x) ] <- 0
    }
    return(x)
  }
)

结果是

$a
[1] 1 4 7

$b
[1] 2 5 0

$c
[1]  3 NA NA

但是,我需要的是返回一个保留值的原始顺序的向量,即:

c( 1,2,3,4,5,NA,7,0,NA )

提前非常感谢。

hopefully this is not a too dumb question, but still being an R beginner I have a serious problem with tapply. Lets say

factors <- as.factor( c("a", "b", "c", "a", "b", "c", "a", "b", "c") )
values  <- c( 1, 2, 3, 4, 5, NA, 7, NA, NA )
tapply(
  values,
  factors,
  function(x){
    if( sum(is.na(x)) == 1 ){
      x[ is.na(x) ] <- 0
    }
    return(x)
  }
)

The result is

$a
[1] 1 4 7

$b
[1] 2 5 0

$c
[1]  3 NA NA

However, what I need is to get a vector back which preserves the original order of values, i.e.:

c( 1,2,3,4,5,NA,7,0,NA )

Many thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

半仙 2024-11-16 11:07:25

在这种情况下,您应该使用 ave 函数:

> ave(values, factors, FUN=function(x) {
+     if( sum(is.na(x)) == 1 ){
+       x[ is.na(x) ] <- 0
+     }
+     return(x)
+   }
+ )
[1]  1  2  3  4  5 NA  7  0 NA

In that case you should use the ave function:

> ave(values, factors, FUN=function(x) {
+     if( sum(is.na(x)) == 1 ){
+       x[ is.na(x) ] <- 0
+     }
+     return(x)
+   }
+ )
[1]  1  2  3  4  5 NA  7  0 NA
相思故 2024-11-16 11:07:25

一个简单的 for 循环可以非常简单地完成此操作:

fun <- function(x){
   if(sum(is.na(x)) == 1){x[is.na(x)] <- 0}
       return(x)
}

for (i in unique(factors)){
   values[i == factors] <- fun(values[i == factors])
}

A simple for loop does this very simply:

fun <- function(x){
   if(sum(is.na(x)) == 1){x[is.na(x)] <- 0}
       return(x)
}

for (i in unique(factors)){
   values[i == factors] <- fun(values[i == factors])
}
岁吢 2024-11-16 11:07:25

一种选择是使用 split() 的替换方法:

## create a copy to store the result after replacement
res <- values

## use split's replacement method to split, apply, and recombine
split(res, factors) <- lapply(split(res, factors),
 function(x){
 if( sum(is.na(x)) == 1 ){
   x[ is.na(x) ] <- 0
 }
  return(x)
 }
)

An option is to use the replacement method for split():

## create a copy to store the result after replacement
res <- values

## use split's replacement method to split, apply, and recombine
split(res, factors) <- lapply(split(res, factors),
 function(x){
 if( sum(is.na(x)) == 1 ){
   x[ is.na(x) ] <- 0
 }
  return(x)
 }
)
凉世弥音 2024-11-16 11:07:25

如果其他人通过搜索如何禁用组的字母排序发现此问题,您可以执行以下操作:

> v=1:4
> group=c("b","b","a","a")
> tapply(v,group,sum)
a b
7 3
> tapply(v,factor(group,unique(group)),sum)
b a
3 7

In case others found this question by searching for how to disable alphabetic sorting for the groups, you can do this:

> v=1:4
> group=c("b","b","a","a")
> tapply(v,group,sum)
a b
7 3
> tapply(v,factor(group,unique(group)),sum)
b a
3 7
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文