Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将值与列名匹配以在R中创建新变量_R - Fatal编程技术网

将值与列名匹配以在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种类型的测试。有什么地方我能读到这个代码的细节吗?@impera
sapply
只是一个循环-它遍历第一个参数的每一项(学生的行号),并将第二个参数中的函数应用于每一项。该函数仅用于在行
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