基于R中的一个列元素名称,在数据帧的其他列中创建一个元素
我有一个列ce、si、ps、se的数据框。我必须根据各自的si列值在ce、ps、se列中创建一个元素。例如,如果si列的值为“SIRR”,则相应的ce、ps、se列值将分别为Newce\U SIRR\U 1、Newps\U SIRR、Newse\U SIRR\U 1。以下是供您参考的数据框 输入:基于R中的一个列元素名称,在数据帧的其他列中创建一个元素,r,R,我有一个列ce、si、ps、se的数据框。我必须根据各自的si列值在ce、ps、se列中创建一个元素。例如,如果si列的值为“SIRR”,则相应的ce、ps、se列值将分别为Newce\U SIRR\U 1、Newps\U SIRR、Newse\U SIRR\U 1。以下是供您参考的数据框 输入: ce si ps se cedummy1 SIRR psdummy sedummy1 cedummy2 SI234
ce si ps se
cedummy1 SIRR psdummy sedummy1
cedummy2 SI234 psdummy sedummy2
cedummy SI67K psdummy sedummy
预期产出:
ce si ps se
Newce_SIRR_1 SIRR Newps_SIRR Newse_SIRR_1
Newce_SI234_2 SI234 Newps_SI234 Newse_SI234_2
Newce_SI67K_3 SI67K Newps_SI67K Newse_SI67K_3
列“si”的值应该附加到每一列的值上,如上面的数据框。对于列“ce”和“se”,序列id应该在末尾
createNewElement <- function(input, element, use_element_in_name, prefix, postfix_sep, include_si_name = FALSE)
{
toappend <- input %>%
mutate(rootname = ifelse(include_si_name, get("si"), if(use_element_in_name) get(element) else "")) %>%
group_by(rootname) %>%
mutate(idname = c(1:n())) %>%
ungroup() %>%
mutate(new_name = paste0(prefix, rootname, postfix_sep, idname))
toappend %>%
mutate(!!element := new_name) %>%
select(-rootname, -idname, -new_name)
}
createNewElement(input, element = "ps", use_element_in_name = FALSE, prefix = "Newps_", postfix_sep = "", include_si_name = TRUE)
createNewElement(input, element = "ce", use_element_in_name = FALSE, prefix = "Newce_", postfix_sep = "_", include_si_name = TRUE)
createNewElement(input, element = "se", use_element_in_name = FALSE, prefix = "NewSe_", postfix_sep = "_", include_si_name = TRUE)
使用
stringr::str_glue
有一个优雅的解决方案:
library(tidyverse)
input %>%
mutate(ce = str_glue("Newce_{si}_{row_number()}"),
ps = str_glue("Newps_{si}"),
se = str_glue("Newse_{si}_{row_number()}"))
给
ce si ps se
<glue> <chr> <glue> <glue>
1 Newce_SIRR_1 SIRR Newps_SIRR Newse_SIRR_1
2 Newce_SI234_2 SI234 Newps_SI234 Newse_SI234_2
3 Newce_SI67K_3 SI67K Newps_SI67K Newse_SI67K_3
ce-si-ps-se
1个新消息1个新消息1个新消息1个新消息
2个新项目234个新项目234个新项目234个新项目234个新项目234个新项目2
3新闻3新闻3新闻
输入数据:
input <- read_table("ce si ps se
cedummy1 SIRR psdummy sedummy1
cedummy2 SI234 psdummy sedummy2
cedummy SI67K psdummy sedummy")
input在base R
中,我们可以使用paste
df1[c(1, 4)] <- Map(function(x, y) paste0("New", y, "_", df1$si,
"_", seq_along(x)), df1[c(1, 4)], names(df1)[c(1, 4)])
df1$ps <- paste0("Newps_", df1$si)
df1[c(1,4)]在我提供了下面的答案之后,我继续调试您的代码。错误出现在ifelse
:由于include\u si\u name
是长度为1的逻辑向量,因此它只收集true
条件的第一个元素(在这种情况下,是get(“si”)
的第一个元素)。若要修复此问题,请将ifelse
中的include_si_name
替换为rep(include_si_name,n())
。我建议改用if\u else
,这会引发错误,而不是假设您只对本例中的第一个元素感兴趣。谢谢,rep(include\u si\u name,n())
工作正常。现在我可以得到每一行的“si”值。我的要求有一些变化,创建了新的问题,下面是链接。你能帮忙吗[
df1[c(1, 4)] <- Map(function(x, y) paste0("New", y, "_", df1$si,
"_", seq_along(x)), df1[c(1, 4)], names(df1)[c(1, 4)])
df1$ps <- paste0("Newps_", df1$si)
df1 <- structure(list(ce = c("cedummy1", "cedummy2", "cedummy"), si = c("SIRR",
"SI234", "SI67K"), ps = c("psdummy", "psdummy", "psdummy"), se = c("sedummy1",
"sedummy2", "sedummy")), class = "data.frame", row.names = c(NA,
-3L))