【问题标题】:replace NA in an R vector with adjacent values用相邻值替换 R 向量中的 NA
【发布时间】:2012-11-10 22:39:24
【问题描述】:

我有一个数据框,其中合并了足球赛季的球员和球队数据 所以对于特定赛季的特定球员,我有类似的数据

df <- data.frame(team=c(NA,"CRP",NA,"CRP","CRP",NA),
             player=c(NA,"Ed",NA,"Ed","Ed",NA),
             playerGame= c(NA,1,NA,2,3,NA),
             teamGame =c(1,2,3,4,5,6)) 

NA 表明该球员没有出现在该特定团队比赛中

如何最有效地分别用“CRP”和“Ed”替换球队和球员的 NA 在这种情况下,plGame 输出为 0,1,1,2,3,3


编辑

抱歉,我在半夜醒来时写了这篇文章,可能过于简化了我的问题。似乎只有一个人意识到这是一组更大数据的子集,即使他/她也没有遵循这一事实,尽管直接硬代码替换球员和球队是不够的 感谢您的回复。 Dsee 对 zoo 包中 na.locf 的提示和 AK 答案的第一行似乎提供了最好的前进方式

df$playerGame[df$teamGame == min(df$teamGame) & is.na(df$playerGame) == TRUE] <- 0
na.locf(df$playerGame)

这涵盖了启动序列的多个 NA 的可能性。在我的情况下, min(df$teamGame) 将始终为 1,因此硬编码可能会加快速度

这里有一个更现实的例子

library(zoo)
library(plyr)

newdf <- data.frame(team=c("CRP","CRP","CRP","CRP","CRP","CRP","TOT","TOT","TOT"),
             player=c(NA,"Ed",NA,"Bill","Bill",NA,NA,NA,"Tom"),
             playerGame= c(NA,1,NA,1,2,NA,NA,NA,1),
             teamGame =c(1,2,3,1,2,3,1,2,3))

我现在可以显示每一行的团队 每支球队在一个赛季中打三场比赛。 Ed 和 Bill,为 CRP 效力,分别出现在第 2 场和第 1,2 场比赛中。汤姆只在第 3 场比赛中为 TOT 效力。假设玩家名称是唯一的(即使在现实世界的数据中)

在我看来,我需要创建另一列“playerTeam”

newdf$playerTeam <- 0

for (i in 1:nrow(newdf)) {
newdf$playerTeam[i] <-ceiling(i/3)
}

然后我可以使用这个值来填补玩家的空白。我已经使用了排序功能 省略 NA

newdf <- ddply(newdf,.(playerTeam),transform,player=sort(player)[1])

然后我可以使用上述代码

newdf$playerGame[newdf$teamGame == 1 & is.na(newdf$playerGame) == TRUE] <- 0
newdf$playerGame <- na.locf(newdf$playerGame)

   team player playerGame teamGame playerTeam
1  CRP     Ed          0        1          1
2  CRP     Ed          1        2          1
3  CRP     Ed          1        3          1
4  CRP   Bill          1        1          2
5  CRP   Bill          2        2          2
6  CRP   Bill          2        3          2
7  TOT    Tom          0        1          3
8  TOT    Tom          0        2          3
9  TOT    Tom          1        3          3

我也需要按季节建造,但这应该不是问题

我这里有什么遗漏吗?

我有几十万行要处理,所以任何加速都会有所帮助。例如,我可能想避免使用 ddply 并使用 data.table 方法或其他应用函数,对

【问题讨论】:

  • 由于在您的示例中团队似乎总是 CRP,您可以将其设置为 CRP:df$team = 'CRP' 但是将团队设置为最接近的非缺失值的想法更有趣,并且我不知道如何去做。我无法为 playerGame 选择模式,因此无法提出创建它的好方法。 playerGame 是否累积玩过游戏?
  • plGame 与其余数据有何关系?你是如何计算你的 0,1,1,2,3,3 的例子的?
  • 第一部分见An introduction to R的第10页和第11页。对于plGame 部分,请参阅library(zoo);?na.locf,或在此网站上搜索类似“[r] NA”的内容
  • @GSee 感谢动物园的建议

标签: r vector replace


【解决方案1】:

要选择 NA,例如 player,请使用

  df$player[is.na(df$player)]

然后为这些使用赋值

  df$player[is.na(df$player)]  <- "Ed"

如果您只想为整个播放器列分配相同的名称,则无需选择任何值:

  df$player[]  <-  "Ed"   # you can omit the brackets [], which are shown just for emphasis

你可以对df$team做同样的事情


附带说明一下,当您创建数据框时,如果您计划添加其他值而不是已经存在的值,您可能需要添加 stringsAsFactors=FALSE
 data.frame( . , stringsAsFactors=FALSE)

【讨论】:

    【解决方案2】:

    用 NA 替换球队和球员:

    df$team[is.na(df$team)] <- "CRP"
    df$player[is.na(df$player)] <- "Ed"
    

    可能有一种更有效的方法来获取相邻值,但可行。

    如果第一个或/和最后一个值为 NA,如您的示例所示,我必须使用另外两行:

    df$playerGame[df$teamGame == min(df$teamGame) & is.na(df$playerGame) == TRUE] <- 0
    df$playerGame[df$teamGame == max(df$teamGame) & is.na(df$playerGame) == TRUE] <- max(df$playerGame, na.rm = TRUE)
    

    对于所有其他观察,这会得到相邻的值:

    df$playerGame[is.na(df$playerGame) == TRUE] <- df$playerGame[-1]
    
    df
    
    team player playerGame teamGame
    CRP     Ed          0        1
    CRP     Ed          1        2
    CRP     Ed          1        3
    CRP     Ed          2        4
    CRP     Ed          3        5
    CRP     Ed          3        6
    

    对于多个团队和/或玩家,我建议将其与 ddply (plyr) 结合使用。

    【讨论】:

    • 感谢您的建议。它适用于这个例子,但不确定它是否适用于 seies 以 2 个 NA 开头的情况
    【解决方案3】:

    你想要的似乎有两部分:

    1. 您想用预先确定的值替换球员姓名和球队
    2. 您希望通过 playerGame 列表结转游戏计数

    对于 (1),您可以这样做:

    df$team[is.na(df$team)] <- 'CRP' 
    

    同样,您可以更改数据框的其他组件

    对于 (2) 你可以这样做:

    if(is.na(df$playerGame[1])) {
        df$playerGame[1] <- 0
    }
    for(i in 2:length(df$playerGame)) { 
        if(is.na(x[i])) {
            df$playerGame[i] <- df$playerGame[i-1]
        }
    } 
    

    那么df$playerGame就是:

    [1] 0 1 1 2 3 3
    

    也许有一个非常漂亮的方法可以做到这一点,但这显然是可读的......

    【讨论】:

    • 由于似乎没有人回答我编辑的版本,我已将您的回答视为已接受,因为第 2 部分是可以接受的,并且是我未来工作的一部分谢谢
    猜你喜欢
    • 1970-01-01
    • 2015-07-28
    • 2021-09-22
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    • 2011-10-04
    • 2020-07-15
    相关资源
    最近更新 更多