在两列上有条件地赋值或删除行
Assign value or delete rows conditionally on two columns
我刚刚在R中合并了纵向数据,发现了一个问题。我的数据框 df(大致)如下所示:
Clinic ID Year Result
A 1 2000 50
A 1 2002
A 1 2004
A 2 2000
A 2 2002
A 2 2004 1100
B 1 2000
B 1 2002
B 1 2004
我们需要具有测试结果的患者所有年份的数据,以及将结果值分配给该患者所有行的方法。我需要丢弃从未记录过结果的患者。在此示例中,我需要保留诊所 A 中患者 1 和 2 的所有行,但丢弃诊所 B 中患者 1 的所有行。此外,在诊所 A 中,我需要患者 1 的所有行都列出“50”,因为是他的测试结果。
我认为最终我可以使用:df[!is.na(df$Result),]...但我不知道如何获得共享给所有人的 'Result' 值删除 NA 之前的相关行。
df <- transform(df, NewResult = (Clinic, ID, Fun=Function(Result) ifelse(Result>0 == Result, NA))
这没有用;它返回了一个错误。非常感谢指导。
我需要的是:
Clinic ID Year Result
A 1 2000 50
A 1 2002 50
A 1 2004 50
A 2 2000 1100
A 2 2002 1100
A 2 2004 1100
B 1 2000 NA
B 1 2002 NA
B 1 2004 NA
我们可以使用 zoo
中的 na.locf
来执行此操作,以便在按 'Clinic' 和 'ID'
分组后用非 NA 值填充 NA 值
library(data.table)
library(zoo)
setDT(df)[, Result := na.locf(na.locf(Result, na.rm = FALSE),
fromLast=TRUE, na.rm = FALSE), .(Clinic, ID)]
或者我们可以使用 tidyverse
中的 fill
library(tidyverse)
df %>%
group_by(Clinic, ID) %>%
fill(Result) %>%
fill(Result, .direction = "up")
# Clinic ID Year Result
# <chr> <int> <int> <int>
#1 A 1 2000 50
#2 A 1 2002 50
#3 A 1 2004 50
#4 A 2 2000 1100
#5 A 2 2002 1100
#6 A 2 2004 1100
#7 B 1 2000 NA
#8 B 1 2002 NA
#9 B 1 2004 NA
我刚刚在R中合并了纵向数据,发现了一个问题。我的数据框 df(大致)如下所示:
Clinic ID Year Result
A 1 2000 50
A 1 2002
A 1 2004
A 2 2000
A 2 2002
A 2 2004 1100
B 1 2000
B 1 2002
B 1 2004
我们需要具有测试结果的患者所有年份的数据,以及将结果值分配给该患者所有行的方法。我需要丢弃从未记录过结果的患者。在此示例中,我需要保留诊所 A 中患者 1 和 2 的所有行,但丢弃诊所 B 中患者 1 的所有行。此外,在诊所 A 中,我需要患者 1 的所有行都列出“50”,因为是他的测试结果。
我认为最终我可以使用:df[!is.na(df$Result),]...但我不知道如何获得共享给所有人的 'Result' 值删除 NA 之前的相关行。
df <- transform(df, NewResult = (Clinic, ID, Fun=Function(Result) ifelse(Result>0 == Result, NA))
这没有用;它返回了一个错误。非常感谢指导。
我需要的是:
Clinic ID Year Result
A 1 2000 50
A 1 2002 50
A 1 2004 50
A 2 2000 1100
A 2 2002 1100
A 2 2004 1100
B 1 2000 NA
B 1 2002 NA
B 1 2004 NA
我们可以使用 zoo
中的 na.locf
来执行此操作,以便在按 'Clinic' 和 'ID'
library(data.table)
library(zoo)
setDT(df)[, Result := na.locf(na.locf(Result, na.rm = FALSE),
fromLast=TRUE, na.rm = FALSE), .(Clinic, ID)]
或者我们可以使用 tidyverse
fill
library(tidyverse)
df %>%
group_by(Clinic, ID) %>%
fill(Result) %>%
fill(Result, .direction = "up")
# Clinic ID Year Result
# <chr> <int> <int> <int>
#1 A 1 2000 50
#2 A 1 2002 50
#3 A 1 2004 50
#4 A 2 2000 1100
#5 A 2 2002 1100
#6 A 2 2004 1100
#7 B 1 2000 NA
#8 B 1 2002 NA
#9 B 1 2004 NA