首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R Tibble整理困境

R Tibble整理困境
EN

Stack Overflow用户
提问于 2019-01-08 05:58:14
回答 2查看 51关注 0票数 1

我正在尝试整理R脚本中的数据,以便可以对整理后的数据集运行一些统计分析。

其中一列列出了对(其中6个),它们对应于输出值的三个单独的“块”。最小可重复数据集如下所示。

代码语言:javascript
复制
dput(head(data, 6)) 
structure(list(pairs = c("ABC", "ACB", "BAC", "BCA", "CBA", "CAB"), block1vals = c(1, 3, 5, 7, 9, 10), block2vals = c(4, 66, 34, 66, 21, 21), block3vals = c(53, 22, 12, 65, 21, 22)), .Names = c("pairs", "block1vals", "block2vals", "block3vals"), row.names = c(NA, 6L), class = "data.frame")

我获得了我的代码来获取这些对,并为每个参与者标记给定块的A/B/C值,每个块对应一列;这是可行的:

区块1:

代码语言:javascript
复制
data$block1types <- sapply(data$pairs, function(x){
  if(x == "ABC") { return("Type A")}
  if(x == "ACB") { return("Type A")}
  if(x == "BAC") { return("Type B")}
  if(x == "BCA") { return("Type B")}
  if(x == "CBA") { return("Type C")}
  if(x == "CAB") { return("Type C")}
})

区块2:

代码语言:javascript
复制
data$block2types <- sapply(data$pairs, function(x){
  if(x == "ABC") { return("Type B")}
  if(x == "ACB") { return("Type C")}
  if(x == "BAC") { return("Type A")}
  if(x == "BCA") { return("Type C")}
  if(x == "CBA") { return("Type B")}
  if(x == "CAB") { return("Type A")}
})

区块3:

代码语言:javascript
复制
data$block3types <- sapply(data$pairs, function(x){
 if(x == "ABC") { return("Type C")}
if(x == "ACB") { return("Type B")}
if(x == "BAC") { return("Type C")}
if(x == "BCA") { return("Type A")}
if(x == "CBA") { return("Type A")}
if(x == "CAB") { return("Type B")}
})

我现在要做的就是重新组织数据,这样就有了一个包含所有"Type A“参与者值的列(不管A在哪个块中),还有一个"Type B”列和一个"Type C“列。

因此,理想的输出是:

代码语言:javascript
复制
data$TypeA <- c(1, 3, 34, 65, 21, 21)
data$TypeB <- c(4, 22, 5, 7, 21, 22)
data$TypeC <- c(53, 66, 12, 66, 9, 10)

我不知道如何做到这一点而不制造问题。我的尝试是这样做的,在数据集之外创建了两列,我希望我可以将它们传播开来:

代码语言:javascript
复制
BlockTypes<- combine(data$block1types, data$block2types, data$block3types, .id = NULL)     
BlockTotals<- combine(data$block1vals, data$block2vals, data$block3vals, .id = NULL) 

然后我尝试这样做:

代码语言:javascript
复制
spread(data, key= BlockTypes, value=BlockTotals, fill = 0)

此操作失败:var的计算结果必须为单个数字或列名,而不是字符向量。不过,我确实认为,更大的问题是将列放在数据集之外。我不能对它们使用扩展函数,因为它们在数据集之外。因此,如果合并功能不能与tibble一起使用,我有点困惑于如何做到这一点。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-08 06:53:52

如果我用心去做,我相信有更好的方法来做这件事,但这里有一些东西是有效的。

首先,我们使用substr函数提取类型的第一个、第二个和第三个字符。我使用粘贴功能将“类型”部分包含在我们执行的提取中。这比像你这样做每一个组合要好得多。

接下来,我们检查了数据3次(每种类型一次)。每次我们浏览数据时,我们都使用块类型来查看是否应该提取块值。

代码语言:javascript
复制
library(tidyverse)
data <- tibble(
pairs = c("ABC", "ACB", "BAC", "BCA", "CBA", "CAB"),
block1vals = c(1, 3, 5, 7, 9, 10),
block2vals = c(4, 66, 34, 66, 21, 21),
block3vals = c(53, 22, 12, 65, 21, 22)
)

data %>%
  mutate(
    block1types = paste0("Type ",substr(pairs, 1, 1)),
    block2types = paste0("Type ",substr(pairs, 2, 2)),
    block3types = paste0("Type ",substr(pairs, 3, 3))) %>%
  mutate(
    TypeAValues = case_when(
    block1types == "Type A" ~ block1vals,
    block2types == "Type A" ~ block2vals,
    block3types == "Type A" ~ block3vals)) %>%
  mutate(
    TypeBValues = case_when(
    block1types == "Type B" ~ block1vals,
    block2types == "Type B" ~ block2vals,
    block3types == "Type B" ~ block3vals)) %>%
  mutate(
    TypeCValues = case_when(
    block1types == "Type C" ~ block1vals,
    block2types == "Type C" ~ block2vals,
    block3types == "Type C" ~ block3vals))
票数 1
EN

Stack Overflow用户

发布于 2019-02-02 10:02:02

这里有一种利用dplyrstringr包的方法。

代码语言:javascript
复制
library(dplyr)
library(stringr)

data %>%
  # For each letter, determine the position of that letter in the entry in the 'pairs' column
  mutate(a = str_locate(pairs, 'A')[,'start'],
         b = str_locate(pairs, 'B')[,'start'],
         c = str_locate(pairs, 'C')[,'start']) %>% 
  # Based on the letter's position, pull the value from the appropriate column
  mutate_at(.vars = vars(a, b, c),
            .funs = funs(case_when(. == 1 ~ block1vals,
                                   . == 2 ~ block2vals,
                                   . == 3 ~ block3vals)))

调用str_locate()的原因很奇怪,因为调用str_locate()的输出是一个矩阵。

下面是该函数的输出:

代码语言:javascript
复制
pairs <- c('ABCDE')
str_locate(pairs, 'BC')

     start end
[1,]     2   3

要只返回字母'B‘的位置,您需要从矩阵中提取标题为start的列。

您可以通过编写以下代码来将对str_locate()的调用与列提取结合起来:

str_locate(pairs, 'BC')['start']

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54082460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档