将值与列名匹配以在R中创建新变量
我有一个像这样的数据集将值与列名匹配以在R中创建新变量,r,R,我有一个像这样的数据集 students <- data.frame(name = c("student1", "student2", "student3", "student4"), test1 = c(50, 30, 20, 6), test2 = c(30, 20, 15, 10), select = c("test2", "test1", "test2", "t
students <- data.frame(name = c("student1", "student2", "student3", "student4"),
test1 = c(50, 30, 20, 6),
test2 = c(30, 20, 15, 10),
select = c("test2", "test1", "test2", "test1"))
学生这里是一个基本的R解决方案:
students$value = with(students, ifelse(select == 'test1', test1, test2))
或当来自dplyr
的case\u时:
library(dplyr)
students %>%
mutate(value = case_when(
select == 'test1' ~ test1,
TRUE ~ test2))
此解决方案还扩展到n
测试
结果:
name test1 test2 select value
1 student1 50 30 test2 30
2 student2 30 20 test1 30
3 student3 20 15 test2 15
4 student4 6 10 test1 6
如果要在base R中执行此操作,并且只有少量测试可供选择,则可以使用以下代码执行此操作:
students$Grade[students$select=="test1"] <- as.numeric(students$test1[students$select=="test1"])
students$Grade[students$select=="test2"] <- as.numeric(students$test2[students$select=="test2"])
下面是一个简单的base-R解决方案
students$grade <- sapply(1:nrow(students),
function(i) students[i, as.character(students$select[i])])
students
name test1 test2 select grade
1 student1 50 30 test2 30
2 student2 30 20 test1 30
3 student3 20 15 test2 15
4 student4 6 10 test1 6
这基本上是将每一行拆分为逗号处的select
,修剪空白,然后将得到的grade
值粘贴在一起
因此,如果上面的students$select[1]
是“test1,test2”
,这将产生
students
name test1 test2 select grade
1 student1 50 30 test1, test2 50, 30
2 student2 30 20 test1 30
3 student3 20 15 test2 15
4 student4 6 10 test1 6
请注意,grade
列现在将被强制设置为字符
格式谢谢!它起作用了。有没有关于如何将其扩展到n个测试的提示?我试图添加'test2'~test2',test3'~test3,它给了我一个错误:mutate_impl(.data,dots)@impera中的错误您将需要select==“testn”~testn
进行每个test
,除了最后一个您指定的TRUE~testn
谢谢!易于用于n种类型的测试。有什么地方我能读到这个代码的细节吗?@imperasapply
只是一个循环-它遍历第一个参数的每一项(学生的行号),并将第二个参数中的函数应用于每一项。该函数仅用于在行i
中查找students
的元素,并在值指定的列名中为行i
选择列。as.character
将select
元素从因子更改为字符串。要查看有关任何函数的帮助,只需在控制台(或RStudio)上键入一个问号即可-例如?sapply
。哇,感谢您的详细解释。这真的很有帮助!有没有办法进行字符串匹配而不是精确匹配?例如,在student1的select
列中,它显示“test2,test1”,我希望在grade列中显示为“50,30”?这正是我想要的。非常感谢你@Andrew!
students$grade <- sapply(1:nrow(students),
function(i) students[i, as.character(students$select[i])])
students
name test1 test2 select grade
1 student1 50 30 test2 30
2 student2 30 20 test1 30
3 student3 20 15 test2 15
4 student4 6 10 test1 6
students$grade <- sapply(1:nrow(students),
function(i) paste(students[i,
trimws(unlist(strsplit(students$select[i], ",")))],
collapse=", "))
students
name test1 test2 select grade
1 student1 50 30 test1, test2 50, 30
2 student2 30 20 test1 30
3 student3 20 15 test2 15
4 student4 6 10 test1 6