对数据帧使用ifelse或case_when



我确信我的问题的解决方案很简单,但我是新的编码,似乎无法在网上找到答案。我正在研究一个由收集和编码的定性数据组成的数据集。数据集包括名为代码1,代码2,代码3,代码4的变量,每个受访者可以有多个代码,他们都至少有一个代码。我试图添加一个变量,将反映给参与者的代码的数量。因此,参与者的数据看起来像这样,数值是我们根据他们的回答分配的代码:

ID Code1 Code2 Code3 Code4
1.  5      NA    NA    NA 
2.  7       6    4     NA
3.  5      12    NA    NA

我想包含的变量名为count,看起来像这样:

ID Code1 Code2 Code3 Code4 Count
1.  5      NA    NA    NA   1
2.  7       6    4     NA   3
3.  5      12    NA    NA   2

第一个参与者的编号是1,因为他们只收到一个编码;参与者2的编号是3,因为他们收到了三个编码;参与者3的编号是2,因为他们只收到了两个编码。

无论如何,我已经尝试使用使用NA的ifelse函数,因为这表明分配了更少的代码,但当我尝试使用它时,我不能分配超过2个结果,这是我的计数变量不能超过两个不同的数字,这些可以达到4。我也试过使用case_when,但得到一个错误消息说错误:Case 7 (!is.na(Code1) ~ 1)必须是一个双面公式,而不是一个逻辑向量。

下面是我尝试过的一个例子:

df$count = ifelse(is.na(df$Code2),1,2)
df$count = ifelse(is.na(Klara$Code3),2,3)
df$count = ifelse(is.na(Klara$Code4),3,4)

我也试过了:

df <- df %>%
mutate(count = case_when(!is.na(Code1) ~ 1, 
!is.na(Code2) ~ 2, 
!is.na(Code3) ~ 3,
!is.na(Code4) ~ 4,
xor(Code1,Code2)))

所以,我无法弄清楚我做错了什么,以及我如何才能得到我需要工作的计数变量。有什么建议吗?

提前感谢!!

希望对大家有所帮助如上所述重新创建数据集

a = c(1, 5, NA, NA, NA)
b = c(2, 7, 6,  4,  NA)
c = c(3, 5, 12, NA, NA)
df <- cbind(a,b,c) %>%
t() %>% 
data.frame() %>% 
setNames(c('id', 'code1', 'code2', 'code3', 'code4')) 

# dplyr片段
df  |> 
na_replace(0)|> 
pivot_longer( code1:code4, names_to = "tag", values_to="count") |> 
group_by(id) |> 
summarise_all(~sum(. != 0)) |> 
select(id, count) |> left_join(df, by =c("id"))

使用rowSumsacrossdplyr方法:

library(dplyr, warn = FALSE)
dat <- dat |>
mutate(count = rowSums(
across(starts_with("Code"), ~ !is.na(.x))
))
dat
#>   ID Code1 Code2 Code3 Code4 count
#> 1  1     5    NA    NA    NA     1
#> 2  2     7     6     4    NA     3
#> 3  3     5    12    NA    NA     2

或使用基数R:

dat$count <- rowSums(
!is.na(dat[grep("^Code", names(dat), value = TRUE)])
)
dat
#>   ID Code1 Code2 Code3 Code4 count
#> 1  1     5    NA    NA    NA     1
#> 2  2     7     6     4    NA     3
#> 3  3     5    12    NA    NA     2

dat <- structure(list(ID = c(1, 2, 3), Code1 = c(5L, 7L, 5L), Code2 = c(
NA,
6L, 12L
), Code3 = c(NA, 4L, NA), Code4 = c(NA, NA, NA)), class = "data.frame", row.names = c(
NA,
-3L
))

我想你在找这样的东西:

重新创建数据(使用tidyverse) -您可以忽略这个

a = c(1, 5, NA, NA, NA)
b = c(2, 7, 6,  4,  NA)
c = c(3, 5, 12, NA, NA)
df <- cbind(a,b,c) %>%
t() %>% 
data.frame() %>% 
setNames(c('id', 'code1', 'code2', 'code3', 'code4')) 

解决方案:

#a
df$count <- rowSums(!is.na(df) & !colnames(df)=='id')
#b
df$count <- apply(df, 1, (x) sum(!is.na(x) & !colnames(df)=='id'))
id code1 code2 code3 code4 count
a  1     5    NA    NA    NA     1
b  2     7     6     4    NA     3
c  3     5    12    NA    NA     2

最新更新