R-还原多个(多列到一列)

  • 本文关键字:还原 一列 r dataframe
  • 更新时间 :
  • 英文 :


我有一个数据集,其中有17个问题调查的答案(10个问题是5个或7个问题是7点级),现在数据格式为我提供了5或7列的列问题答案(是或错误),就像一种单式编码样式一样。我想将这些列转换回15列。

更具体,我看起来像以下数据

        Q1.1  Q1.2  Q1.3 Q1.4 Q1.5 Q1.6 Q1.7 .... Q17.1 Q17.2 ... Q17.5 
row1     T     F      F    F    F    F    F         F     T          F
  ...               ...
row2000  F     T      F    F    F    F    F         T     F          F

我想要的格式是

        Q1  Q2 .... Q17
row1    1    4       2  # with number indicating the value that the column is True
           ....
row2000 2    3       1  #(e.g., if Q2.4 is T, then for Q2, it is 4).

基本r方法使用split.defaultmax.col。使用split.default,我们可以根据其名称中的模式将列分开,以便将每个问题分为列表。假设每个问题都只有一个TRUE值,我们可以使用max.col查找TRUE索引。

sapply(split.default(df, sub("\..*", "", names(df))), max.col)
#     Q1 Q2
#[1,]  1  2
#[2,]  6  5

数据

df <-read.table(text = "Q1.1 Q1.2 Q1.3 Q1.4 Q1.5 Q1.6 Q1.7 Q2.1 Q2.2  Q2.3 Q2.4 Q2.5
T     F      F    F    F    F    F         F     T          F F F
F     F      F    F    F    T    F         F     F          F F T", header = T)

这是假设您的数据类是"逻辑"。如果" t"/" f"以字符格式存储(例如在@Maurits答案中),则需要先将其转换为逻辑。

使用@Maurits Evers的数据

df[] <- lapply(df, as.logical)
sapply(split.default(df, sub("\..*", "", names(df))), max.col)
#     Q1 Q17
#[1,]  1   2
#[2,]  2   1

这是tidyverse选项:

library(tidyverse)
df %>%
    rownames_to_column("row") %>%
    gather(k, v, -row) %>%
    separate(k, c("question", "part"), sep = "\.") %>%
    filter(v == "T") %>%
    group_by(row) %>%
    select(-v) %>%
    spread(question, part)
## A tibble: 2 x 3
## Groups:   row [2]
#  row     Q1    Q17
#  <chr>   <chr> <chr>
#1 row1    1     2
#2 row2000 2     1

我假设您的原始数据包含"T"/"F"作为character条目。如果它们实际上是TRUE/FALSE,则应将filter(v == "T")更改为filter(v == TRUE)


样本数据

df <- read.table(text =
    "Q1.1  Q1.2  Q1.3 Q1.4 Q1.5 Q1.6 Q1.7  Q17.1 Q17.2  Q17.5
row1     T     F      F    F    F    F    F         F     T          F
row2000  F     T      F    F    F    F    F         T     F          F", colClasses = "character")

最新更新