【问题标题】:Comparing column values with rowSums将列值与 rowSums 进行比较
【发布时间】:2021-02-06 04:31:31
【问题描述】:

我正在尝试使用 rowSums 但对条件值进行比较。

这是我的数据框示例,基于调查。其中行表示参与者,列表示孩子的出生日期。

  b3_01 b3_02 b3_03 b3_04 b3_05 b3_06
1  1360  1360  1266  1228  1181  1158    
2  1362  1342  1301  1264  1245  1191 
3  1379    NA    NA    NA    NA    NA  
4  1355  1330  1293  1293  1227  1208  
5  1391  1371  1358  1334  1311  1311

在这里,类似的日期是指双胞胎。我想做的是创建一个新列,告诉我每行有多少次这些列的值是相似的。这会给我类似的东西:

  b3_01 b3_02 b3_03 b3_04 b3_05 b3_06 twins
1  1360  1360  1266  1228  1181  1158     1
2  1362  1342  1301  1264  1245  1191     0
3  1379    NA    NA    NA    NA    NA     0
4  1355  1330  1293  1293  1227  1208     1
5  1391  1371  1358  1334  1311  1311     1

编辑:对不起,我忘了说如果任何数字出现 3 次或更多次,它不应该被算作双胞胎。最终目标是有 4 列:一列用于单胞胎(每个数字仅出现一次),一列用于双胞胎,一列用于三胞胎(如果任何数字出现 3 次),一列用于四胞胎。

我正在使用 dplyr。由于 data.frame 非常大,我需要指定要比较的列范围。我已经尝试了以下代码以及变体:

twins<-df%>%
  mutate(twins= rowSums(select(.,starts_with("b3_")) == select(.,starts_with("b3_")),na.rm=TRUE))

这不起作用。我也玩过其他功能,但找不到解决方案。

您对如何实现这一目标有任何想法吗?我觉得解决方案很简单,但我是 R 的绝对初学者。

【问题讨论】:

  • 如果一行有 3 个相同的数字(所有其他数字不同),您会将它们视为一对双胞胎还是两个?更一般地说,如果一行包含 n 乘以相同的值,您要计算 n-1 twins 还是 1 twin?
  • 我不会把他们算作双胞胎。理想情况下,我想创建 4 个新列:1 个用于单胞胎(每个数字出现一次),2 个用于双胞胎(如果任何数字只出现两次),3 个用于三胞胎(如果任何数字出现 3 次,一个用于四胞胎。这是否有效或使您的答案无效?顺便说一句,谢谢
  • 那么我的回答中table 的逻辑非常好。您将获得单胞胎的数量为sum(table==1),双胞胎的数量为sum(table==2),三胞胎的数量为sum(table==3)。我会更新我的答案。

标签: r count comparison dplyr


【解决方案1】:

一个简单的解决方案是

twins <- df%>%
  mutate(twins = apply(., 1, function(x) sum(duplicated(x, incomparables=NA))))

【讨论】:

  • 我非常喜欢您的解决方案!但是,您知道一种计算重复两次的值的方法吗?我想为重复两次、三次或四次的值创建单独的列。 (见编辑)
【解决方案2】:

参考我的评论,假设n连续相同的值被算作n-1双胞胎,定义

countTwins <- function(row) {
  length(row)-length(unique(row))
}

twins列为

twinCol <- apply(df,1,countTwins)

如果您想计算 n1 twin 相同的值,请改用函数

countTwins2 <- function(row) {
  sum(table(unname(unlist(row)))>1)
}

根据我的评论更新:

countSinglesTwinsAndTriplets <- function(row) {
  tt <- table(unname(unlist(row)))
  c(sum(tt==1),sum(tt==2),sum(tt==3)) #nr of singletons,twins,triplets
}

addCols <- setNames(data.frame(t(apply(df,1,countSinglesTwinsAndTriplets))),c("singletons","twins","triplets"))

【讨论】:

    【解决方案3】:

    其他解决方案

    基础

    df$twins <- apply(df, 1, function(x) length(x) - length(unique(x)) - sum(is.na(x)) + any(is.na(x)))
    
      b3_01 b3_02 b3_03 b3_04 b3_05 b3_06 twins
    1  1360  1360  1266  1228  1181  1158     1
    2  1362  1342  1301  1264  1245  1191     0
    3  1379    NA    NA    NA    NA    NA     0
    4  1355  1330  1293  1293  1227  1208     1
    5  1391  1371  1358  1334  1311  1311     1
    

    【讨论】:

      【解决方案4】:

      @Taufi 使用的类似逻辑,但添加了purrr

      df %>%
       mutate(twins = pmap(across(everything()), ~ sum(duplicated(na.omit(c(...))))))
      
        b3_01 b3_02 b3_03 b3_04 b3_05 b3_06 twins
      1  1360  1360  1266  1228  1181  1158     1
      2  1362  1342  1301  1264  1245  1191     0
      3  1379    NA    NA    NA    NA    NA     0
      4  1355  1330  1293  1293  1227  1208     1
      5  1391  1371  1358  1334  1311  1311     1
      

      【讨论】:

        猜你喜欢
        • 2019-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-24
        • 2020-12-30
        相关资源
        最近更新 更多