首页 > 解决方案 > 在多个列中搜索给定的值选择及其相关标签

问题描述

我有一个 12 列的数据框,下面的数据框是一个简化的例子。

    ID <- c(1, 1, 2, 2, 3, 3, 4, 4, 5, 5)                                   
    period<- c(1, 2, 1, 2, 1, 2, 1, 2, 1, 2)                            
    column1<- c(100, 400, 500, 300, 700, 800, 300, 100, 1100, 100)      
    column2<- c(1500, 100,800,900,100,1100,1200,200,100,400)            
    column3<- c(200, 1000, 200,NA,500,800,1100,300,100,2000)                    
    df<- data.frame(ID, period, column1, column2, column3) 

ID period column1 column2 column3
1      1     100    1500     200
1      2     400     100    1000
2      1     500     800     200
2      2     300     900      NA
3      1     700     100     500
3      2     800    1100     800
4      1     300    1200    1100
4      2     100     200     300
5      1    1100     100     100
5      2     100     400    2000

1)我对值 100、200 和 300 很感兴趣,如果这些值在 column1 到 column3 中可用,我想添加一个新列(第 4 列),如果这些值不可用,则包含 0。

2)如果这些值(100、200、300)可用,我想从lookup_table 中查找属于这些值的名称。

agent_number<- c(100, 200, 300)
agent_name<- c("agent1", "agent2", "agent3")
lookup_table<- data.frame(agent_number, agent_name)

这是我想要的输出。

ID period column1 column2 column3 column4 column5 column6 column7
 1      1     100    1500     200       1  agent1  agent2    <NA>
 1      2     400     100    1000       1  agent1    <NA>    <NA>
 2      1     500     800     200       1  agent2    <NA>    <NA>
 2      2     300     900      NA       0  agent3    <NA>    <NA>
 3      1     700     100     500       1  agent1    <NA>    <NA>
 3      2     800    1100     800       0    <NA>    <NA>    <NA>
 4      1     300    1200    1100       1  agent3    <NA>    <NA>
 4      2     100     200     300       1  agent1  agent2  agent3
 5      1    1100     100     100       1  agent1  agent1    <NA>
 5      2     100     400    2000       1  agent1    <NA>    <NA>

对于问题1,我已经尝试过了,但没有奏效。

agent_number<- c("100", "200", "300")
df %>% select(ID, column1:column3) %>%
mutate_at(vars(column1:column3),list(~ ifelse(. == agent_number, 1, 0)))

对于问题 2,我对原始数据框中的 12 列中的每一列都使用了 left_join,但在合并表后无法将 column1 的名称更改为 12。我每次都得到与下面相同的输出。

left_join(df, lookup_table, by=c("column1"="agent_number"), suffix = c("", ".1"), suffixes_mandatory = c(FALSE, TRUE))
left_join(df, lookup_table, by=c("column2"="agent_number"), suffix = c("", ".2"), suffixes_mandatory = c(FALSE, TRUE))
ID period column1 column2 column3 agent_name
 1      1     100    1500     200       <NA>
 1      2     400     100    1000       <NA>
 2      1     500     800     200       <NA>
 2      2     300     900      NA       <NA>
 3      1     700     100     500       <NA>
 3      2     800    1100     800       <NA>
 4      1     300    1200    1100       <NA>
 4      2     100     200     300       <NA>
 5      1    1100     100     100       <NA>
 5      2     100     400    2000       <NA>

我有大型数据文件,我正在寻找一个运行速度不是很慢的代码。非常感谢您的任何建议。

标签: rdplyr

解决方案


data.table 解决方案:

# Convert your dataframe to a data.table with setDT
setDT(df)

# Initiate column to all zeros
df$column4 <- 0
# Where column1, column2, or column3 is in 100,200,300
df[column1 %in% c(100,200,300) | 
   column2 %in% c(100,200,300) | 
   column3 %in% c(100,200,300), 
   column4 := 1]

# Begin to map values
df$column5 <- NA
df$column6 <- NA
df$column7 <- NA

# Map values solution from 
#https://stackoverflow.com/questions/20565949/replace-values-in-data-frame-with-other-values-according-to-a-rule
require(plyr)
df$column5 <- mapvalues(df$column1, 
          from=c(100,200,300), 
          to=c("agent1","agent2","agent3"))
df$column6 <- mapvalues(df$column2, 
          from=c(100,200,300), 
          to=c("agent1","agent2","agent3"))
df$column7 <- mapvalues(df$column3, 
          from=c(100,200,300), 
          to=c("agent1","agent2","agent3"))

推荐阅读