如何合并来自同一 Dataframe 的多个列名相似的列?

x6h2sr28  于 2023-07-31  发布在  其他
关注(0)|答案(2)|浏览(110)

首先,如果格式不对,很抱歉,这是我的第一个问题,我对R相对较新。
我有一个大型数据集,看起来或多或少像这样:
| 性别|问题1_1|问题1_2|问题1_3| QUESTION1_3 |
| --|--|--|--| ------------ |
| F级|不适用|不适用|不适用| NA |
| 中|1| 0| 1| 1 |
| 中|不适用|不适用|不适用| NA |
| F级|0| 0| 1| 1 |
| 中|不适用|不适用|不适用| NA |
问题被分散的原因是因为参与者被要求选择“所有适用的”。
现在,我希望通过列名将所有问题1合并在一起,如果问题得到回答,则显示一个值,如果问题没有得到回答,则显示另一个值(或者保持NA)-只是为了查看每个问题(而不是问题中的每个选项)有多少个答案。
理想情况下,我希望有一个代码,可以让我通过列名中的部分字符串匹配来合并列,因为数据集非常大,但我可以手动完成。
我最接近的方法是使用tidiverse包手动完成:

dat_joined <- as.data.frame(dat) %>%
  unite("QUESTION1", 3:5, remove = TRUE)

字符串
但它以一种奇怪的格式连接列:
| 性别|问题1| QUESTION1 |
| --|--| ------------ |
| F级|不适用不适用不适用| NA_NA_NA |
| 中|1_0_1| 1_0_1 |
| 中|不适用不适用不适用| NA_NA_NA |
| F级|0_0_1| 0_0_1 |
| 中|不适用不适用不适用| NA_NA_NA |
有什么解决办法吗?我真的很难做到这一点,因为我在这里发现的大多数问题都集中在合并列,其中答案通过部分字符串匹配,而不是列名。
此外,我最终将不得不研究每一个选项,我很难知道从哪里开始。有没有什么资源可以让我查一下?
这是一些代码来复制玩具表

ID<- c("100001", "100002", "100003", "100004", "100005")
gender <- c("F","M","M","F","M")
QUESTION1_1<- c(NA, "1",NA,"0",NA)
QUESTION1_2<- c(NA, "0",NA,"0",NA)
QUESTION1_3<- c(NA, "1",NA,"0",NA)

dat<- cbind(ID,gender,QUESTION1_1,QUESTION1_2,QUESTION1_3)
dat

vlju58qv

vlju58qv1#

如果我正确理解了你的问题,这应该是可行的:

library(dplyr)
library(tidyr)
library(stringr)

dat <- as_tibble(dat) # turn dat into a tibble

# Pivot longer 
long_dat <- 
  pivot_longer(
    dat,
    cols = starts_with("QUESTION"),
    names_to = "question_name",
    values_to = "response") |> 
  mutate(response = as.numeric(response))
# (response is coded as a character variable in your example)

head(long_dat)
#> # A tibble: 6 × 4
#>   ID     gender question_name response
#>   <chr>  <chr>  <chr>            <dbl>
#> 1 100001 F      QUESTION1_1         NA
#> 2 100001 F      QUESTION1_2         NA
#> 3 100001 F      QUESTION1_3         NA
#> 4 100002 M      QUESTION1_1          1
#> 5 100002 M      QUESTION1_2          0
#> 6 100002 M      QUESTION1_3          1

## Group dat by ID and question number,
## which we work out from the text of the question name
group_by(long_dat,
         ID, question_number = str_extract(question_name, "\\d+(?=_)")) |> 
  ## Summarise - is the sum of sub-questions greater than 0?
  summarise(any_responses = sum(response) > 0)

#> # A tibble: 5 × 3
#> # Groups:   ID [5]
#>   ID     question_number any_responses
#>   <chr>  <chr>           <lgl>   
#> 1 100001 1               NA      
#> 2 100002 1               TRUE    
#> 3 100003 1               NA      
#> 4 100004 1               FALSE   
#> 5 100005 1               NA

字符串
创建于2023-07-24带有reprex v2.0.2

liwlm1x9

liwlm1x92#

使用pivot_longer,它非常简单:

library(tidyverse)

df <- df %>% 
  pivot_longer(starts_with("QUESTION"), names_pattern = "QUESTION(\\d+)_(\\d+)", names_to = c("question", "option"), values_drop_na = T) %>%
  mutate(across(-gender, as.numeric),
        gender = as.factor(gender))

# Output
# A tibble: 6 × 5
      ID gender question option value
   <dbl> <fct>     <dbl>  <dbl> <dbl>
1 100002 M             1      1     1
2 100002 M             1      2     0
3 100002 M             1      3     1
4 100004 F             1      1     0
5 100004 F             1      2     0
6 100004 F             1      3     1

字符串
从这里你可以问一些问题,比如我有多少个数据点(勾选选项)?(6,上面的行数),或者通过以下方式获得回答问题的数量:

df %>% 
  select(ID, question) %>%
  distinct() %>%
  nrow()
# [1] 2

相关问题