我有一个看起来像这样的数据集
user_id <- c(12345,12345,12345,12345,12345,12356,12356,12356,12356,12356)
r1 <- c(1,NA,NA,NA,NA,1,NA,NA,NA,NA)
r2 <- c(NA,1,NA,NA,NA,NA,1,NA,NA,NA)
r3 <- c(NA,NA,1,NA,NA,NA,NA,1,NA,NA)
r4 <- c(NA,NA,NA,1,NA,NA,NA,NA,1,NA)
r5 <- c(NA,NA,NA,NA,1,NA,NA,NA,NA,1)
df <- data.frame(user_id,r1,r2,r3,r4,r5)
我希望能够删除空格(我的数据实际上在这些空格中有NA),以便每个用户ID只有一行,所有评级都在同一行。我试过用这篇文章来弄清楚事情,但我想把它作为一个数据框架等。到目前为止,原始帖子中的流程对我来说并没有起作用。理想情况下,我想坚持整洁的宇宙,但在这一点上,我只是试图使它工作。
将其转为长格式通常在这里很有帮助,因为它允许我们更容易地使用分组变量;在这种情况下,删除所有具有""
的行,然后再次旋转到宽格式。
library(dplyr)
library(tidyr)
df %>%
pivot_longer(-user_id) %>%
filter(value != "") %>%
pivot_wider(names_from="name")
当为"NA
"时,将"filter1
"命令修改为"filter(!value %in% NA)
",
# A tibble: 2 × 6
user_id r1 r2 r3 r4 r5
<dbl> <chr> <chr> <chr> <chr> <chr>
1 12345 1 1 1 1 1
2 12356 1 1 1 1 1
另一个使用gather
和spread
的选项:
user_id <- c(12345,12345,12345,12345,12345,12356,12356,12356,12356,12356)
r1 <- c(1,NA,NA,NA,NA,1,NA,NA,NA,NA)
r2 <- c(NA,1,NA,NA,NA,NA,1,NA,NA,NA)
r3 <- c(NA,NA,1,NA,NA,NA,NA,1,NA,NA)
r4 <- c(NA,NA,NA,1,NA,NA,NA,NA,1,NA)
r5 <- c(NA,NA,NA,NA,1,NA,NA,NA,NA,1)
df <- data.frame(user_id,r1,r2,r3,r4,r5)
library(dplyr)
library(tidyr)
df %>%
gather(key, value, -user_id) %>%
na.omit() %>%
spread(key, value)
#> user_id r1 r2 r3 r4 r5
#> 1 12345 1 1 1 1 1
#> 2 12356 1 1 1 1 1
由reprex包(v2.0.1)创建于2022-06-30
使用base R,假设您的实际数据具有相同的规律:
df |>
stack() |>
subset(values != "" & (ind != "user_id" | !duplicated(values))) |>
unstack()
# user_id r1 r2 r3 r4 r5
# 1 12345 1 1 1 1 1
# 2 12356 1 1 1 1 1