繁体   English   中英

一次更改多列的值——model.matrix()?

[英]Changing values of many columns at once -- model.matrix()?

这是我目前拥有的结构的 dput() 。

structure(list(id = c(1, 1, 2, 4, 4), country = c("USA", "Japan",  "Germany", "Germany", "USA"), USA = c(0, 0, 0, 0, 0), Germany = c(0,  0, 0, 0, 0), Japan = c(0, 0, 0, 0, 0)), class = "data.frame", row.names = c(NA,  -5L))

我想编辑此数据框以获得以下结果,以便将此方法应用于具有 100k+ 观察值的数据集。 具体来说,我想使用来自( df$country )的信息来描述分配给特定 ID 的国家(例如, id == 1country == Japan ),并使用相应的列名(例如,a名为“日本”的列)等于 1。请注意,ID 不是唯一的!

这就是我想要结束的:

structure(list(id = c(1, 1, 2, 4, 4), country = c("USA", "Japan",  "Germany", "Germany", "USA"), USA = c(1, 1, 0, 1, 1), Germany = c(0,  0, 1, 1, 1), Japan = c(1, 1, 0, 0, 0)), class = "data.frame", row.names = c(NA,  -5L))

下面的代码给出了一个接近的结果:

df[levels(factor(df$country))] = model.matrix(~country - 1, df)

但最终给了我以下错误的结构:

structure(list(id = c(1, 1, 2, 4, 4), country = c("USA", "Japan", 
"Germany", "Germany", "USA"), USA = c(1, 0, 0, 0, 1), Germany = c(0, 
0, 1, 1, 0), Japan = c(0, 1, 0, 0, 0)), row.names = c(NA, -5L
), class = "data.frame") 

如何编辑上述命令以产生我想要的结果? 不能使用数据透视,因为实际上,我正在处理许多在“国家”列中具有不同值的数据集,一旦数据透视,将产生具有不统一的列/结构的数据集,这将阻碍以后的数据分析。

感谢您的任何帮助!

也许这有帮助

library(dplyr)
df %>% 
    mutate(across(USA:Japan, ~  +(country == cur_column()))) %>% 
    group_by(id) %>% 
    mutate(across(USA:Japan, max)) %>% 
    ungroup

-输出

# A tibble: 5 × 5
     id country   USA Germany Japan
  <dbl> <chr>   <int>   <int> <int>
1     1 USA         1       0     1
2     1 Japan       1       0     1
3     2 Germany     0       1     0
4     4 Germany     1       1     0
5     4 USA         1       1     0

或将model.matrix修改为

m1 <- model.matrix(~country - 1, df)
m1[] <- ave(c(m1), df$id[row(m1)], col(m1), FUN = max)

您可以使用基础R

re <- rle(df$id)
for(j in re$values){
    y <- which(j == df$id)
        df[y , match(df$country[y] , colnames(df))] <- 1
}
  • 输出
  id country USA Germany Japan
1  1     USA   1       0     1
2  1   Japan   1       0     1
3  2 Germany   0       1     0
4  4 Germany   1       1     0
5  4     USA   1       1     0

您是否正在为您的封闭问题寻找这样的解决方案(组合) CRAN R - 一次将值“1”分配给许多虚拟变量

@akrun 提供的解决方案在这里解决了这个问题。 但你可能会寻找这样的东西:

library(dplyr)

df %>% 
  group_by(id) %>% 
  mutate(across(-country, ~case_when(country == cur_column() ~ 1))) %>% 
  fill(-country, .direction = "updown") %>% 
  mutate(across(-country, ~ifelse(is.na(.), 0, .))) %>% 
  ungroup()
     id country   USA Germany Japan
  <dbl> <chr>   <dbl>   <dbl> <dbl>
1     1 USA         1       0     1
2     1 Japan       1       0     1
3     2 Germany     0       1     0
4     4 Germany     1       1     0
5     4 USA         1       1     0

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM