这是我的数据框示例。它来自原始问题在调查中的一个问题:“您在哪里?在所有要标记的地方做标记。”
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语句,但是一直出现错误。有什么建议?谢谢!
答案 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