将数据框中的字符串向量转换为 R 中的分类变量
Turning vectors of strings in a dataframe into categorical variables in R
我是 R 的新手,我确信有一种方法可以在不使用循环的情况下执行以下操作,我对此比较熟悉。
举个例子,你有一堆每个人都喜欢的名字和水果:
name <- c("Alice", "Bob")
preference <- list(c("apple", "pear"), c("banana", "apple"))
df <- as.data.frame(cbind(name, preference))
如何将其转换为以下内容?
apple <- c(1, 1)
pear <- c(1, 0)
banana <- c(0, 1)
df2 <- data.frame(name, apple, pear, banana)
我的基本直觉是先提取所有水果,然后循环检查每个水果是否符合每一行的偏好:
fruits <- unique(unlist(df$preference))
for (fruit in fruits) {
df <- df %>% rowwise %>% mutate("{fruit}" := fruit %in% preference)
}
这似乎可行,但我很确定有更好的方法。
df %>%
unnest(everything()) %>%
xtabs(~., .) %>%
as.data.frame.matrix() %>%
rownames_to_column('name')
name apple banana pear
1 Alice 1 0 1
2 Bob 1 1 0
在tidyverse
(假设'preference'是一个list
列),unnest
然后'preference'再用pivot_wider
重塑回到 'wide' 格式 values_fn
为 length
library(dplyr)
library(tidyr)
df %>%
unnest_longer(preference) %>%
pivot_wider(names_from = preference, values_from = preference,
values_fn = length, values_fill = 0)
-输出
# A tibble: 2 × 4
name apple pear banana
<chr> <int> <int> <int>
1 Alice 1 1 0
2 Bob 1 0 1
数据
df <- data.frame(name, preference = I(preference))
另一种可能的解决方案,基于 tidyr::separate_rows
和 janitor::tabyl
:
library(tidyverse)
df %>%
separate_rows(everything(), sep="(?<=\w), (?=\w)") %>%
janitor::tabyl(name, preference)
#> name apple banana pear
#> Alice 1 0 1
#> Bob 1 1 0
我是 R 的新手,我确信有一种方法可以在不使用循环的情况下执行以下操作,我对此比较熟悉。
举个例子,你有一堆每个人都喜欢的名字和水果:
name <- c("Alice", "Bob")
preference <- list(c("apple", "pear"), c("banana", "apple"))
df <- as.data.frame(cbind(name, preference))
如何将其转换为以下内容?
apple <- c(1, 1)
pear <- c(1, 0)
banana <- c(0, 1)
df2 <- data.frame(name, apple, pear, banana)
我的基本直觉是先提取所有水果,然后循环检查每个水果是否符合每一行的偏好:
fruits <- unique(unlist(df$preference))
for (fruit in fruits) {
df <- df %>% rowwise %>% mutate("{fruit}" := fruit %in% preference)
}
这似乎可行,但我很确定有更好的方法。
df %>%
unnest(everything()) %>%
xtabs(~., .) %>%
as.data.frame.matrix() %>%
rownames_to_column('name')
name apple banana pear
1 Alice 1 0 1
2 Bob 1 1 0
在tidyverse
(假设'preference'是一个list
列),unnest
然后'preference'再用pivot_wider
重塑回到 'wide' 格式 values_fn
为 length
library(dplyr)
library(tidyr)
df %>%
unnest_longer(preference) %>%
pivot_wider(names_from = preference, values_from = preference,
values_fn = length, values_fill = 0)
-输出
# A tibble: 2 × 4
name apple pear banana
<chr> <int> <int> <int>
1 Alice 1 1 0
2 Bob 1 0 1
数据
df <- data.frame(name, preference = I(preference))
另一种可能的解决方案,基于 tidyr::separate_rows
和 janitor::tabyl
:
library(tidyverse)
df %>%
separate_rows(everything(), sep="(?<=\w), (?=\w)") %>%
janitor::tabyl(name, preference)
#> name apple banana pear
#> Alice 1 0 1
#> Bob 1 1 0