根据R中的现有列创建新列

时间:2020-01-29 21:26:20

标签: r dataframe if-statement

这是我的数据框示例。它来自原始问题在调查中的一个问题:“您在哪里?在所有要标记的地方做标记。”

Code   Option1   Option2   Option3   Option4
101        A        C         NA        NA
102        B        D         NA        NA
103        A        B         D         NA
104        D        NA        NA        NA
105        A        B         C         D

我想转换此数据,以便每一列都是位置之一,如果您位于4个位置中的任何一个位置,您将得到0/1:

Code   A   B   C   D
101    1   0   1   0
102    0   1   0   1
103    1   1   0   1
104    0   0   0   1
105    1   1   1   1

我尝试使用ifelse语句,但是一直出现错误。有什么建议?谢谢!

4 个答案:

答案 0 :(得分:2)

使用tidyverse

library(dplyr)
library(tidyr)
df1 %>%
    pivot_longer(cols = -Code, values_drop_na = TRUE) %>% 
    mutate(n = 1) %>% 
    select(-name) %>% 
    pivot_wider(names_from = value, values_from = n, values_fill = list(n = 0)) %>%
    select(Code, LETTERS[1:4])
#   Code A B C D
#1  101 1 0 1 0
#2  102 0 1 0 1
#3  103 1 1 0 1
#4  104 0 0 0 1
#5  105 1 1 1 1

或使用mtabulate

library(qdapTools)
cbind(df1[1], +(mtabulate(as.data.frame(t(df1[-1]))) > 0))

或使用melt/dcast

library(data.table)
dcast(melt(setDT(df1), id.var = 'Code', na.rm = TRUE), Code ~ value, length)

答案 1 :(得分:0)

我是在使用gsub将True / False调查响应转换为二进制1,0时完成的:

t <- function(x) gsub("A",1,x)
f <- function(x) gsub("B",0,x)

df[1:4] <- lapply(df[1:4], t)
df[1:4] <- lapply(df[1:4], f)

我敢肯定有更好的方法可以做到这一点,但这对我有用。

答案 2 :(得分:0)

您可以尝试:

tab <- table(cbind(df[1], unlist(df[-1])))
cbind(Code = row.names(tab), as.data.frame.matrix(tab), row.names = NULL)

  Code A B C D
1  101 1 0 1 0
2  102 0 1 0 1
3  103 1 1 0 1
4  104 0 0 0 1
5  105 1 1 1 1

答案 3 :(得分:0)

假设“ df1”是您的表,这种方法需要多几行,但很容易理解:

library(tidyverse)
library(reshape2)

df1 %>% 
  gather(Code) %>% 
  dcast(Code ~ value, fun.aggregate=length) %>%
  select(-'NA')

您的结果是:

  Code A B C D
1  101 1 0 1 0
2  102 0 1 0 1
3  103 1 1 0 1
4  104 0 0 0 1
5  105 1 1 1 1
相关问题