等效的 SAS 格式(在 R 中)
Equivalent of SAS format (in R)
假设我有一个数据框:
sick <- c("daa12", "daa13", "daa14", "daa15", "daa16", "daa17")
code <- c("heart", "heart", "lung", "lung", "cancer", "cancer")
sick_code <- data.frame(sick, code)
还有一个:
pid <- abs(round(rnorm(6)*1000,0))
sick <- c("-" , "-", "-", "-", "daa16", "SO")
p_sick <- data.frame(pid, sick)
现在我想向 p_sick 添加一个新的变量,即 "translates" p_sick$sick 到 sick_code$code。 p_sick$sick 中的变量是一个字符串,它可能是也可能不是 p_sick$sick,在这种情况下应该返回 NA。
现在我可以用一个简单的 ifelse 语句编写 for 循环。但是我的数据有 1.5 亿行,而 translate table 有 15.000 行。
我用谷歌搜索发现这是 SaS 中 "proc format" 的等价物(但我无权访问 SaS,也不知道它是如何工作的)。
也许是 plyr 中合并的某种变体,或者应用函数?
编辑:我接受了这两个答案,因为它们有效。
我将尝试研究两者之间的差异(速度)。由于合并是一个内置函数,我猜它会做很多检查。
EDIT2:对于通过 Google 到达这里的人们; merge has and sort = FALSE 这将加快速度。请注意,订单不会以任何方式保留。
您可以将 merge
与 all.x = TRUE
一起使用(以保持 p_sick
中的值与 sick_code
中的值不匹配:
merge(p_sick, sick_code, all.x = TRUE)
等效项是使用 dplyr 中的 left_join
:
library(dplyr)
left_join(p_sick, sick_code)
# pid sick code
# 1 212 - <NA>
# 2 2366 - <NA>
# 3 325 - <NA>
# 4 269 - <NA>
# 5 501 daa16 cancer
# 6 1352 SO <NA>
请注意,这些解决方案中的每一个都有效,因为名称 sick
在两个数据帧之间共享。假设它们有不同的名称 - 假设该列在 sick_code
中称为 sickness
。您可以分别使用:
merge(p_sick, sick_code, by.x = "sick", by.y = "sickness", all.x = TRUE)
# or
left_join(p_sick, sick_code, c(sick = "sickness"))
data.table
将适用于您的示例:
library(data.table)
setkey(setDT(p_sick),sick)
p_sick[setDT(sick_code),code := i.code][]
pid sick code
1: 3137 - NA
2: 755 - NA
3: 1327 - NA
4: 929 - NA
5: 939 daa16 cancer
6: 906 SO NA
详情请见。
一个简单的命名向量也可以。命名向量可以充当查找。因此,与其将 sick 和 code 定义为数据框,不如将其定义为命名向量并将其用作解码器。像这样:
# Set up named vector
sick_decode <- c("heart", "heart", "lung", "lung", "cancer", "cancer")
names(sick_decode) <- c("daa12", "daa13", "daa14", "daa15", "daa16", "daa17")
# Prepare data
pid <- abs(round(rnorm(6)*1000,0))
sick <- c("-" , "-", "-", "-", "daa16", "SO")
p_sick <- data.frame(pid, sick)
# Create new variable using decode
p_sick$sick_decode <- sick_decode[p_sick$sick]
# Results
#> pid sick sick_decode
#> 1 511 - <NA>
#> 2 1619 - <NA>
#> 3 394 - <NA>
#> 4 641 - <NA>
#> 5 53 daa16 cancer
#> 6 244 SO <NA>
我怀疑此方法也会很快,但尚未对其进行基准测试。
此外,现在有一个专门用于在 R 中复制 SAS 格式功能的 R 包。它称为 fmtr。
假设我有一个数据框:
sick <- c("daa12", "daa13", "daa14", "daa15", "daa16", "daa17")
code <- c("heart", "heart", "lung", "lung", "cancer", "cancer")
sick_code <- data.frame(sick, code)
还有一个:
pid <- abs(round(rnorm(6)*1000,0))
sick <- c("-" , "-", "-", "-", "daa16", "SO")
p_sick <- data.frame(pid, sick)
现在我想向 p_sick 添加一个新的变量,即 "translates" p_sick$sick 到 sick_code$code。 p_sick$sick 中的变量是一个字符串,它可能是也可能不是 p_sick$sick,在这种情况下应该返回 NA。
现在我可以用一个简单的 ifelse 语句编写 for 循环。但是我的数据有 1.5 亿行,而 translate table 有 15.000 行。
我用谷歌搜索发现这是 SaS 中 "proc format" 的等价物(但我无权访问 SaS,也不知道它是如何工作的)。
也许是 plyr 中合并的某种变体,或者应用函数?
编辑:我接受了这两个答案,因为它们有效。 我将尝试研究两者之间的差异(速度)。由于合并是一个内置函数,我猜它会做很多检查。
EDIT2:对于通过 Google 到达这里的人们; merge has and sort = FALSE 这将加快速度。请注意,订单不会以任何方式保留。
您可以将 merge
与 all.x = TRUE
一起使用(以保持 p_sick
中的值与 sick_code
中的值不匹配:
merge(p_sick, sick_code, all.x = TRUE)
等效项是使用 dplyr 中的 left_join
:
library(dplyr)
left_join(p_sick, sick_code)
# pid sick code
# 1 212 - <NA>
# 2 2366 - <NA>
# 3 325 - <NA>
# 4 269 - <NA>
# 5 501 daa16 cancer
# 6 1352 SO <NA>
请注意,这些解决方案中的每一个都有效,因为名称 sick
在两个数据帧之间共享。假设它们有不同的名称 - 假设该列在 sick_code
中称为 sickness
。您可以分别使用:
merge(p_sick, sick_code, by.x = "sick", by.y = "sickness", all.x = TRUE)
# or
left_join(p_sick, sick_code, c(sick = "sickness"))
data.table
将适用于您的示例:
library(data.table)
setkey(setDT(p_sick),sick)
p_sick[setDT(sick_code),code := i.code][]
pid sick code
1: 3137 - NA
2: 755 - NA
3: 1327 - NA
4: 929 - NA
5: 939 daa16 cancer
6: 906 SO NA
详情请见
一个简单的命名向量也可以。命名向量可以充当查找。因此,与其将 sick 和 code 定义为数据框,不如将其定义为命名向量并将其用作解码器。像这样:
# Set up named vector
sick_decode <- c("heart", "heart", "lung", "lung", "cancer", "cancer")
names(sick_decode) <- c("daa12", "daa13", "daa14", "daa15", "daa16", "daa17")
# Prepare data
pid <- abs(round(rnorm(6)*1000,0))
sick <- c("-" , "-", "-", "-", "daa16", "SO")
p_sick <- data.frame(pid, sick)
# Create new variable using decode
p_sick$sick_decode <- sick_decode[p_sick$sick]
# Results
#> pid sick sick_decode
#> 1 511 - <NA>
#> 2 1619 - <NA>
#> 3 394 - <NA>
#> 4 641 - <NA>
#> 5 53 daa16 cancer
#> 6 244 SO <NA>
我怀疑此方法也会很快,但尚未对其进行基准测试。
此外,现在有一个专门用于在 R 中复制 SAS 格式功能的 R 包。它称为 fmtr。