如何更改r中的数据帧行和列?

如何更改r中的数据帧行和列?,r,dataframe,R,Dataframe,存在具有多个值的数据帧​​在一列中 我想更改此数据框的行和列 像这样 #load libraries library(dplyr) library(tidyr) #calculate number of rows to generate tmp <- df %>% group_by(id, type) %>% mutate(tmp = n()) %>% summarise(tmp = max(tmp)) %>% group_by(id) %>%

存在具有多个值的数据帧​​在一列中

我想更改此数据框的行和列

像这样

#load libraries
library(dplyr)
library(tidyr)

#calculate number of rows to generate
tmp <- df %>% group_by(id, type) %>%
  mutate(tmp = n()) %>%
  summarise(tmp = max(tmp)) %>%
  group_by(id) %>%
  summarise(tmp = prod(tmp))

#store this value in variable n
n <- tmp$tmp  

#final code
df %>% pivot_wider(names_from = type, values_from = value, 
                   values_fn = function(x){
                     l <- list(x)
                     list(rep(l[[1]], n/length(l[[1]])))
                   }) %>%
  unnest(-id)

# A tibble: 6 x 5
     id A     B     C     D    
  <int> <chr> <chr> <chr> <chr>
1     1 A1    B1    C1    D1   
2     1 A1    B2    C2    D1   
3     1 A1    B1    C3    D1   
4     1 A1    B2    C1    D1   
5     1 A1    B1    C2    D1   
6     1 A1    B2    C3    D1
数据:

结果:


我该怎么办?

编辑假设在输入中添加了两行
1,D,D2
2,A,A1
,我需要检查您的输出

旧答案实际上,您希望为每个id分配cols A到D的每个可用值。因此,我使用了一个临时代码来计算必须首先由
tmp
代码为每个id生成的行数。此后,我通过更广泛地旋转数据并最终将列表复制到所需的次数来收集值

像这样跟着走

#load libraries
library(dplyr)
library(tidyr)

#calculate number of rows to generate
tmp <- df %>% group_by(id, type) %>%
  mutate(tmp = n()) %>%
  summarise(tmp = max(tmp)) %>%
  group_by(id) %>%
  summarise(tmp = prod(tmp))

#store this value in variable n
n <- tmp$tmp  

#final code
df %>% pivot_wider(names_from = type, values_from = value, 
                   values_fn = function(x){
                     l <- list(x)
                     list(rep(l[[1]], n/length(l[[1]])))
                   }) %>%
  unnest(-id)

# A tibble: 6 x 5
     id A     B     C     D    
  <int> <chr> <chr> <chr> <chr>
1     1 A1    B1    C1    D1   
2     1 A1    B2    C2    D1   
3     1 A1    B1    C3    D1   
4     1 A1    B2    C1    D1   
5     1 A1    B1    C2    D1   
6     1 A1    B2    C3    D1
请试试这个

wide_df <- df %>% group_by(type) %>% 
  mutate(row= row_number()) %>% 
  pivot_wider(names_from = type,values_from = value) %>%
  select(-row)
wide_df%group_by(type)%%>%
变异(行=行编号())%>%
透视图(名称从=类型,值从=值)%>%
选择(-行)

我认为您可以使用
取消堆叠
展开。如果顺序不重要且未使用
id
,则网格可以执行此操作:

expand.grid(unstack(x[3:2]))
#   A  B  C  D
#1 A1 B1 C1 D1
#2 A1 B2 C1 D1
#3 A1 B1 C2 D1
#4 A1 B2 C2 D1
#5 A1 B1 C3 D1
#6 A1 B2 C3 D1
数据:


x遗憾的是,发布的答案没有得到正确的结果

所以我用我的方法得到了结果,但我不知道这是否是一种有效的方法

df <- data.frame(id = 1, type = c("A", "B", "B", "C", "C", "C", "D")
            , val = c("A1", "B1", "B2", "C1", "C2", "C3", "D1"))
tmp <- aggregate(val~id+type, df, toString) 
result_df <- tmp %>%  spread(key = "type", value = "val") %>%
  separate_rows(A, sep=",") %>% separate_rows(B, sep=",") %>% separate_rows(C, sep=",") %>% separate_rows(D, sep=",")
df%分隔行(B,sep=“,”)%>%分隔行(C,sep=“,”)%>%分隔行(D,sep=“,”)
结果:


无论如何,非常感谢大家

如果源样本数据有一个额外的行,比如
1,D,D2
,那么您的输出将是什么?我认为在这种情况下,输出将包含12行
(1*2*3*2)
。我说得对吗?是的。你是对的。这只是一个例子,在实践中​​差异很大。我认为当有超过1个id时,这将不起作用。这就是为什么我编写了
id
。如果应该使用
id
,最好知道是否每次都有所有类型。但目前尚未提供此信息。请同意。OP没有澄清你检查过它的输出了吗?我得到了错误的结果。。。T.T
df <- data.frame(id = 1, type = c("A", "B", "B", "C", "C", "C", "D")
            , val = c("A1", "B1", "B2", "C1", "C2", "C3", "D1"))
tmp <- aggregate(val~id+type, df, toString) 
result_df <- tmp %>%  spread(key = "type", value = "val") %>%
  separate_rows(A, sep=",") %>% separate_rows(B, sep=",") %>% separate_rows(C, sep=",") %>% separate_rows(D, sep=",")