Поиск нескольких столбцов для заданного выбора значений и их связанных меток - PullRequest
0 голосов
/ 23 февраля 2019

У меня есть фрейм данных с 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 до 3 или 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 я использовал left_join для каждого из 12 столбцов в моем исходном фрейме данных, но не смог изменить имена 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 голосов
/ 23 февраля 2019

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"))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...