当前位置:  开发笔记 > 数据库 > 正文

如何在R中使用查找表而不创建重复项?

如何解决《如何在R中使用查找表而不创建重复项?》经验,为你挑选了1个好方法。

我想知道是否有人有一个很好的方法来实现这一目标.我有一个数据框,其中属于特定组(=条件)的每个观察(=项目)具有给定值:

# Create sample data.
item       = rep(1:3,2)                               #6 items
condition  = c(rep("control",3), rep("related",3))    #2 conditions
value      = c(10,11,12,20,21,22)                     #6 values          
df         = data.frame(item, condition, value)

  item condition value
1    1   control    10
2    2   control    11
3    3   control    12
4    1   related    20
5    2   related    21
6    3   related    22

我还有一个查找表,其中包含每组的平均值:

# Create lookup table.
condition  = c("control", "related")
mean       = c(11,21)
table      = data.frame(condition, mean)

  condition mean
1   control   11
2   related   21

我想修改我的原始数据帧,使得它包含一个新列label,其中说:" ",如果该项目的值低于集团平均,而" ",否则.它应该如下所示:

# How the output should look like.
# If the item value is less than the group mean, write "low". Write "high" otherwise.
item       = rep(1:3,2)                               
condition  = c(rep("control",3), rep("related",3))    
value      = c(10,11,12,20,21,22)                      
label      = c(rep(c("low", "high", "high"),2))
output     = data.frame(item, condition, value, label)

  item condition value label
1    1   control    10   low
2    2   control    11  high
3    3   control    12  high
4    1   related    20   low
5    2   related    21  high
6    3   related    22  high

如果这只是将组平均值复制到原始数据框中,我会使用merge.但我需要的是考虑组平均值,为每个项目写一个新标签,根据组平均值显示" "或" ".

我尝试的一件事是首先将我的数据框与表合并,然后用于ifelse比较value列和mean列.这有效,但我最终在我的数据框中有一个平均列,我不需要(我只需要标签列).当然,我可以手动删除平均列,但看起来很笨重.所以我想知道:有人知道一个更好/更优雅的解决方案吗?

谢谢你!



1> G. Grothendi..:

这是一些替代方案.(1)和(2)仅使用基数R和(2),(3)和(5)不创建仅明确删除的平均列.在(1),(3)和(4)中,我们使用左连接,尽管内连接将给出与该数据相同的结果,并且在(1a)的情况下允许我们将(1)写为单行.

1)合并

m <- merge(df, table, all.x = TRUE)
transform(m, label = ifelse(value < mean, "low", "high"), mean = NULL)

赠送:

  item condition value label
1    1   control    10   low
2    2   control    11  high
3    3   control    12  high
4    1   related    20   low
5    2   related    21  high
6    3   related    22  high

1a)通过内连接,它可以缩短为:

transform(merge(df, table), label = ifelse(value < mean, "low", "high"), mean = NULL)

2)匹配

transform(df, 
  label = ifelse(value < table$mean[match(condition, table$condition)], "low", "high")
)

给予同样的.

3)sqldf

library(sqldf)
sqldf("select 
         df.*, 
         case when value < mean 
              then 'low' 
              else 'high' 
              end label
       from df 
       left join 'table' using (condition)")

4)dplyr

library(dplyr)
df %>%
   left_join(table) %>%
   mutate(label = ifelse(value < mean, "low", "high")) %>%
   select(- mean)

5)data.table

library(data.table)
dt <- as.data.table(df)
setkey(dt, "condition")
dt[table, label := ifelse(value < mean, "low", "high")]

推荐阅读
夏晶阳--艺术
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有