我想知道是否有一种方法可以在 for 循环中使用 mutate()
函数从 R 中的列表创建多个列。
以下是我的意思的示例:
问题:
我有一个数据框df
,它有两列:类别和评级。我想为 df$category 的每个元素添加一列,并且在该列中,如果类别列与迭代器匹配,我想要一个 1。
library(dplyr)
df <- tibble(
category = c("Art","Technology","Finance"),
rating = c(100,95,50)
)
手动执行,我可以这样做:
df <-
df %>%
mutate(art = ifelse(category == "Art", 1,0))
但是,当我有 50 个类别时会发生什么? (这与我原来的问题很接近。那会花费很多时间!)
我尝试过的:
category_names <- df$category
for(name in category_names){
df <-
df %>%
mutate(name = ifelse(category == name, 1,0))
}
不幸的是,它似乎不起作用。
如果您能提供有关该主题的任何信息,我将不胜感激!
完整代码:
library(dplyr)
#Creates tibble
df <- tibble(
category = c("Art","Technology","Finance"),
rating = c(100,95,50)
)
#Showcases the operation I would like to loop over df
df <-
df %>%
mutate(art = ifelse(category == "Art", 1,0))
#Creates a variable for clarity
category_names <- df$category
#For loop I tried
for(name in category_names){
df <-
df %>%
mutate(name = ifelse(category == name, 1,0))
}
我知道我本质上所做的是model.matrix()
的一种形式;然而,在我发现这个功能之前,我仍然很困惑为什么我之前所做的事情不起作用。
最佳答案
我们可以在创建序列列后使用pivot_wider
library(dplyr)
library(tidyr)
df %>%
mutate(rn = row_number(), n = 1) %>%
pivot_wider(names_from = category, values_from = n,
values_fill = list(n = 0)) %>%
select(-rn)
# A tibble: 3 x 4
# rating Art Technology Finance
# <dbl> <dbl> <dbl> <dbl>
#1 100 1 0 0
#2 95 0 1 0
#3 50 0 0 1
或者另一个选项是 map
library(purrr)
map_dfc(unique(df$category), ~ df %>%
transmute(!! .x := +(category == .x))) %>%
bind_cols(df, .)
# A tibble: 3 x 5
# category rating Art Technology Finance
#* <chr> <dbl> <int> <int> <int>
#1 Art 100 1 0 0
#2 Technology 95 0 1 0
#3 Finance 50 0 0 1
如果我们需要一个for
循环
for(name in category_names) df <- df %>% mutate(!! name := +(category == name))
或者在带有table
的base R
中
cbind(df, as.data.frame.matrix(table(seq_len(nrow(df)), df$category)))
# category rating Art Finance Technology
#1 Art 100 1 0 0
#2 Technology 95 0 0 1
#3 Finance 50 0 1 0
关于r - 如何使用 mutate 从 for 循环中的列表创建列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61471128/