在多列中搜索给定的值选择及其相关标签

时间:2019-02-23 04:01:44

标签: r dplyr

我有一个包含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感兴趣,并且我想添加一个新列(第4列),如果第1列中的这些值可用,则该列包含1;如果这些值不可用,则添加0。 / p>

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>

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

1 个答案:

答案 0 :(得分:1)

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"))