融化数据并用所需数据填充新列

时间:2019-12-01 21:06:18

标签: r

Hello编码社区

我有一个分为两部分的问题,得到了 1/2 回答

  1. 按我喜欢的方式转置(也称为融合)数据框-完成
  2. 根据在“已移出”列(在转置步骤中创建的列)中找到的结果添加数据行-卡在此处

    df<- read.table("https://pastebin.com/raw/NEPcUG01",header=T, sep="\t")
    df_transformed<-tidyr::gather(df, day, removed, -(1:2), na.rm = TRUE) # melted data
    

在我的示例(df)中,我进行了8天的实验。在某些日子里,我删除了数据点,而我只对这几天感兴趣(因此为什么我在转置过程中添加了na.rm = TRUE)。有时我会删除1个数据点或4个数据点(但这实际上可以是任何数字)

我希望将删除的数据点称为“个人”,并按时间顺序对其进行计数。因此,我首先需要添加一个名为“个人”的列

    df_transformed$individual <- ""

我想根据“已删除”列中的结果填写“个人”列。

示例:机架2仅删除了1个数据点,并且在day_8。因此,我想在“个人”列中添加1。另一方面,笼4的day_5(1个数据点)和day_7(3个数据点)中的数据点被删除了,总共有4个数据点,又名4个“个人”。因此,在笼4中,从day_5开始,我想在“个人”列中添加1,对于第7天,创建总共3行数据,并以2,3,4继续“个人计数”。如果day_8删除了3个数据点,则单个计数将继续为5,6,7。

今天我的示例数据集的理想结果是:

    desired_results <- read.table("https://pastebin.com/raw/r7QrC0y3", header=T, sep="\t") # 68 total rows of data

有趣的一条信息:我的最终数据集中的行总数应等于所有已删除数据点的总和:

    sum(df_transformed$removed) # 68

谢谢您的StackOverflow社区。期待看到结果。

2 个答案:

答案 0 :(得分:1)

我们可以使用complete创建一个从1到由individualcage分组的每个day的序列。然后,我们fillexperimentremoved中的NA值。

library(dplyr)
library(tidyr)

df_transformed %>%
  mutate(individual = removed) %>%
  group_by(cage, day) %>%
  complete(individual = seq_len(individual)) %>%
  fill(experiment, removed, .direction = "up")

#   cage   day individual   experiment removed
#1     2 day_8          1        sugar       1
#2     3 day_5          1        sugar       1
#3     4 day_5          1        sugar       3
#4     4 day_5          2        sugar       3
#5     4 day_5          3        sugar       3
#6     4 day_7          1        sugar       1
#7     7 day_7          1        sugar       1
#8     7 day_8          1        sugar       1
#9     8 day_5          1        sugar       2
#10    8 day_5          2        sugar       2
# … with 58 more rows

要仅基于individual更新cage,我们可以

df_transformed %>%
  mutate(individual = removed) %>%
  group_by(cage, day) %>%
  complete(individual = seq_len(individual)) %>%
  group_by(cage) %>%
  mutate(individual = row_number()) %>%
  fill(experiment, removed, .direction = "up")

答案 1 :(得分:0)

我认为以下代码可以满足您的需求:

library(tidyverse)

read.table("https://pastebin.com/raw/NEPcUG01",header=T, sep="\t") %>%
    pivot_longer(starts_with("day_"), names_to = "day", values_to = "removed") %>%
    # drop_na() %>%
    group_by(cage) %>%
    summarize(individual = sum(removed, na.rm = TRUE)) 

我使用了管道运算符(%>%),它可以使语法更简洁。我还使用了较新的pivot_longer函数来代替collect。然后,按笼子分组,然后用summarize对单个列求和,您可以得出每个笼子中除去了多少个人。

我检查了所有个人的总和,这似乎可行:

read.table("https://pastebin.com/raw/NEPcUG01",header=T, sep="\t") %>%
    pivot_longer(starts_with("day_"), names_to = "day", values_to = "removed") %>%
    # drop_na() %>%
    group_by(cage) %>%
    summarize(individual = sum(removed, na.rm = TRUE)) %>%
    pull(individual) %>%
    sum()

#> [1] 68

结果与您想要的结果略有不同。我不是100%,您所期望的结果实际上是正确的...从您的问题中,我知道笼4应该有4个人,但是在您的desired_result中,它出现4次,值分别为1,2,3和4。我发送给您的代码会生成一个数据框,每个框都显示在一行中。