【问题标题】:R: NA and dcast [duplicate]R:NA和dcast [重复]
【发布时间】:2021-09-15 10:02:48
【问题描述】:

我正在使用 R 编程语言。

假设我有以下数据:

my_data <- data.frame(

"id" = c("1", "1", "1", "1", "2", "2", "2", "2" ),
"name" = c("john", "jason", "jack", "jim", "john", "jason", "jack", "jim" ),
"points" = c("150", "165", "183", "191", "151", "166", "184", "192"),
"gender" = c("male", "male", "male", "male", "male", "male", "male", "male"),
"country" = c("usa", "usa", "usa", "usa", "usa", "usa", "usa", "usa")
)

#view original data format
 my_data

  id  name points gender country
1  1  john    150   male     usa
2  1 jason    165   male     usa
3  1  jack    183   male     usa
4  1   jim    191   male     usa
5  2  john    151   male     usa
6  2 jason    166   male     usa
7  2  jack    184   male     usa
8  2   jim    192   male     usa

假设对于上述数据:“gender”和“country”将始终具有相同的值。此外,这 4 个名字总是一起出现 - 每次它们一起出现时,它们的“id”都是同一个数字。唯一可以改变的数字是它们从迭代到迭代的“点”数(即它们的“id”)。

这是我想要做的:

my_data_1 <- data.frame(

"id" = c("1", "2"),
"john_points" = c("150", "151"),
"jason_points" = c("165", "166"),
"jack_points" = c("183", "184"),
"jim_points" = c("191", "192"),
"gender" = c("male", "male"),
"country" = c("usa", "usa")
)

#view desired data format

  my_data_1
  id john_points jason_points jack_points jim_points gender country
1  1         150          165         183        191   male     usa
2  2         151          166         184        192   male     usa

我找到了这个以前的stackoverflow帖子How to reshape data from long to wide format,其中“data.table”库和“dcast”函数可以用来解决这类问题。

我尝试了“dcast”功能的不同组合,但我无法让最终结果看起来像预期的那样:

 library(data.table)
 
#attempt 1 : not correct
 setDT(my_data)
dcast(my_data, name ~ points, value.var = c("gender", "country", "id")
)
    name gender_150 gender_151 gender_165 gender_166 gender_183 gender_184 gender_191 gender_192 country_150 country_151 country_165 country_166 country_183 country_184 country_191
1:  jack       <NA>       <NA>       <NA>       <NA>       male       male       <NA>       <NA>        <NA>        <NA>        <NA>        <NA>         usa         usa        <NA>
2: jason       <NA>       <NA>       male       male       <NA>       <NA>       <NA>       <NA>        <NA>        <NA>         usa         usa        <NA>        <NA>        <NA>
3:   jim       <NA>       <NA>       <NA>       <NA>       <NA>       <NA>       male       male        <NA>        <NA>        <NA>        <NA>        <NA>        <NA>         usa
4:  john       male       male       <NA>       <NA>       <NA>       <NA>       <NA>       <NA>         usa         usa        <NA>        <NA>        <NA>        <NA>        <NA>
   country_192 id_150 id_151 id_165 id_166 id_183 id_184 id_191 id_192
1:        <NA>   <NA>   <NA>   <NA>   <NA>      1      2   <NA>   <NA>
2:        <NA>   <NA>   <NA>      1      2   <NA>   <NA>   <NA>   <NA>
3:         usa   <NA>   <NA>   <NA>   <NA>   <NA>   <NA>      1      2
4:        <NA>      1      2   <NA>   <NA>   <NA>   <NA>   <NA>   <NA>

#attempt 2 : not correct

 setDT(my_data)
 dcast(my_data, name ~ points, value.var = c("gender", "country"))
    name gender_150 gender_151 gender_165 gender_166 gender_183 gender_184 gender_191 gender_192 country_150 country_151 country_165 country_166 country_183 country_184 country_191
1:  jack       <NA>       <NA>       <NA>       <NA>       male       male       <NA>       <NA>        <NA>        <NA>        <NA>        <NA>         usa         usa        <NA>
2: jason       <NA>       <NA>       male       male       <NA>       <NA>       <NA>       <NA>        <NA>        <NA>         usa         usa        <NA>        <NA>        <NA>
3:   jim       <NA>       <NA>       <NA>       <NA>       <NA>       <NA>       male       male        <NA>        <NA>        <NA>        <NA>        <NA>        <NA>         usa
4:  john       male       male       <NA>       <NA>       <NA>       <NA>       <NA>       <NA>         usa         usa        <NA>        <NA>        <NA>        <NA>        <NA>
   country_192
1:        <NA>
2:        <NA>
3:         usa
4:        <NA>

#attempt 3 - not correct:

 setDT(my_data)
dcast(my_data, name ~ points, value.var = c("id"))
    name  150  151  165  166  183  184  191  192
1:  jack <NA> <NA> <NA> <NA>    1    2 <NA> <NA>
2: jason <NA> <NA>    1    2 <NA> <NA> <NA> <NA>
3:   jim <NA> <NA> <NA> <NA> <NA> <NA>    1    2
4:  john    1    2 <NA> <NA> <NA> <NA> <NA> <NA>

有人可以告诉我如何解决这个问题吗?为什么有这么多?是否有可能像我展示的那样拥有决赛桌(即 my_data_1)?是否可以按name_points的格式重命名变量(例如john_points)?

谢谢

【问题讨论】:

  • dcast(setDT(my_data), id + gender + country ~ name, value.var = 'points')tidyr::pivot_wider(my_data, names_from = name, values_from = points, names_prefix = 'points_')

标签: r datatable data-manipulation na


【解决方案1】:

我会使用tidyr,因为从长格式更改为宽格式非常简单。

library(tidyr)
wide = my_data %>% 
  tidyr::spread(name, points)

结果

  id gender country jack jason jim john
1  1   male     usa  183   165 191  150
2  2   male     usa  184   166 192  151

【讨论】:

  • 非常感谢您的回答!我正在使用一台没有互联网且没有 USB 端口的旧电脑。我只有 R 和一些预安装的库(例如 base R、dplyr、data.table、reshape2)。我没有任何“整洁”的库。您知道解决此问题的更“基本”方法吗?谢谢!
  • 是否可以添加“性别”列?是否可以在每个人的姓名旁边添加“_points”?非常感谢您的帮助!
猜你喜欢
  • 2016-07-28
  • 2016-05-02
  • 1970-01-01
  • 2013-10-04
  • 2015-07-30
  • 2018-12-10
  • 2021-11-26
  • 1970-01-01
  • 2017-06-29
相关资源
最近更新 更多